From 885939fabff048441284788fd0c493e6278d6400 Mon Sep 17 00:00:00 2001 From: Juszoe Date: Tue, 13 Aug 2019 23:51:02 +0800 Subject: [PATCH] =?UTF-8?q?v1.0=20=E5=A2=9E=E5=8A=A0HR=E7=AD=9B=E9=80=89?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E7=A8=B3=E5=AE=9A=E6=80=A7=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AB=99=E7=82=B9=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 33 +++++++-- nexusphp.py | 191 +++++++++++++++++++++++++++++++++------------------- site.md | 14 ++++ 3 files changed, 163 insertions(+), 75 deletions(-) create mode 100644 site.md diff --git a/README.md b/README.md index f5cbea2..e58d8a9 100644 --- a/README.md +++ b/README.md @@ -22,21 +22,22 @@ C:\Users\\flexget\plugins\ # Windows 1. 编辑flexget配置文件,添加nexusphp选项,按照需要进行配置 ``` yaml nexusphp: - cookie: 'you_cookie' - discount: + cookie: 'you_cookie' # 必填 + discount: # 优惠信息 选填 - free - 2x - 2x50% - 2xfree - 50% - 30% - seeders: + seeders: # 做种情况 选填 min: 1 max: 2 - leechers: + leechers: # 下载情况 选填 min: 10 max: 100 max_complete: 0.8 + hr: no # 是否下载HR 选填 ``` 2. 为rss的other_fields字段添加link属性 ``` yaml @@ -72,12 +73,14 @@ flexget execute 数字,最大下载人数,默认不限制 #### `max_complete` 小数,范围`0-1.0` 下载者中最大完成度,超过这个值将不下载,默认为1 +### hr +yes或no,是否下载HR,默认不考虑HR,即可能下载到HR ## 完整配置示例 ### 免费热种 ``` yaml tasks: - task_name: + my-free-task: rss: url: https://www.example.com/rss.xml other_fields: @@ -98,7 +101,7 @@ tasks: ### 热种 ``` yaml tasks: - task_name: + my-hot-task: rss: url: https://www.example.com/rss.xml other_fields: @@ -111,6 +114,19 @@ tasks: min: 20 download: ~/flexget/torrents/ ``` +### 避免HR +``` yaml +tasks: + no-hr-task: + rss: + url: https://www.example.com/rss.xml + other_fields: + - link + nexusphp: + cookie: 'you_cookie' + hr: no + download: ~/flexget/torrents/ +``` ## 常见问题 #### 我的python版本是2.X如何使用? @@ -125,9 +141,12 @@ pip3 install flexget # 使用pip3安装 以下站点名使用别称或简称,欢迎反馈更多可用或不可用的站点 - 任何未修改关键结构的nexusphp站点 - 铂金家 -- 馒头 +- 馒头(站点安全性较高,使用flexget ip与登录ip不同时可能无法使用) - nice - 菠萝 - OB - 天空 - 学校 + +#### 如何判断站点是否支持 +[判断站点以及适配站点](https://github.com/Juszoe/flexget-nexusphp/blob/master/site.md) \ No newline at end of file diff --git a/nexusphp.py b/nexusphp.py index f3769a5..7cc0723 100644 --- a/nexusphp.py +++ b/nexusphp.py @@ -1,7 +1,11 @@ +# coding=utf-8 from __future__ import unicode_literals, division, absolute_import +from builtins import * import concurrent.futures +from requests.adapters import HTTPAdapter + from flexget import plugin from flexget.config_schema import one_or_more from flexget.event import event @@ -10,6 +14,7 @@ class NexusPHP(object): """ + 配置示例 task_name: rss: url: https://www.example.com/rss.xml @@ -27,6 +32,7 @@ class NexusPHP(object): min: 1 max: 100 max_complete: 0.8 + hr: no """ schema = { @@ -37,18 +43,19 @@ class NexusPHP(object): 'seeders': { 'type': 'object', 'properties': { - 'min': {'type': 'integer', 'minimum': 0}, - 'max': {'type': 'integer', 'minimum': 0} + 'min': {'type': 'integer', 'minimum': 0, 'default': 0}, + 'max': {'type': 'integer', 'minimum': 0, 'default': 100000} } }, 'leechers': { 'type': 'object', 'properties': { - 'min': {'type': 'integer', 'minimum': 0}, - 'max': {'type': 'integer', 'minimum': 0}, - 'max_complete': {'type': 'number', 'minimum': 0, 'maximum': 1} + 'min': {'type': 'integer', 'minimum': 0, 'default': 0}, + 'max': {'type': 'integer', 'minimum': 0, 'default': 100000}, + 'max_complete': {'type': 'number', 'minimum': 0, 'maximum': 1, 'default': 1} } - } + }, + 'hr': {'type': 'boolean'} }, 'required': ['cookie'] } @@ -57,20 +64,19 @@ def build_conifg(self, config): config = dict(config) config.setdefault('discount', None) config.setdefault('seeders', {'min': 0, 'max': 100000}) - config['seeders'].setdefault('min', 0) - config['seeders'].setdefault('max', 100000) config.setdefault('leechers', {'min': 0, 'max': 100000, 'max_complete': 1}) - config['leechers'].setdefault('min', 0) - config['leechers'].setdefault('max', 100000) - config['leechers'].setdefault('max_complete', 1) + config.setdefault('hr', None) return config - @plugin.priority(-1) def on_task_filter(self, task, config): config = self.build_conifg(config) + adapter = HTTPAdapter(max_retries=5) + task.requests.mount('http://', adapter) + task.requests.mount('https://', adapter) + def consider_entry(_entry, _link): - discount, seeders, leechers = NexusPHP._get_info(task, _link, config['cookie']) + discount, seeders, leechers, hr = NexusPHP._get_info(task, _link, config['cookie']) seeder_max = config['seeders']['max'] seeder_min = config['seeders']['min'] leecher_max = config['leechers']['max'] @@ -81,6 +87,10 @@ def consider_entry(_entry, _link): _entry.reject('%s does not match discount' % discount) # 优惠信息不匹配 return + if config['hr'] is not None: + if hr != config['hr']: + _entry.reject('hr is %s' % hr) # HR信息不匹配 + if len(seeders) not in range(seeder_min, seeder_max + 1): _entry.reject('%d is out of range of seeder' % len(seeders)) # 做种人数不匹配 return @@ -115,78 +125,91 @@ def consider_entry(_entry, _link): @staticmethod # 解析页面,获取优惠、做种者信息、下载者信息 - def info_from_page(detail_page, peer_page): + def info_from_page(detail_page, peer_page, discount_fn=None, hr_fn=None): soup = get_soup(detail_page.content, 'html.parser') try: - discount_class = soup.find('h1', id='top').b.font['class'][0] # selector: '#top > b:nth-child(1) > font' - discount_table = { - 'free': 'free', - 'twoup': '2x', - 'twoupfree': '2xfree', - 'thirtypercent': '30%', - 'halfdown': '50%', - 'twouphalfdown': '2x50%' - } - discount = discount_table[discount_class] - except AttributeError: + if discount_fn is None: + def discount_fn(page): + convert = { + 'free': 'free', + 'twoup': '2x', + 'twoupfree': '2xfree', + 'thirtypercent': '30%', + 'halfdown': '50%', + 'twouphalfdown': '2x50%' + } + for key, value in convert.items(): + if key in page.text: + return value + return None + discount = discount_fn(detail_page) + except Exception: discount = None # 无优惠 - def get_peers(table): - peers = [] - name_index = 0 - connectable_index = 1 - uploaded_index = 2 - downloaded_index = 4 - completed_index = 7 - for index, tr in enumerate(table.find_all('tr')): - try: - if index == 0: - tds = tr.find_all('td') - for i, td in enumerate(tds): - text = td.get_text() - if text == '用户' or text == '用戶': - name_index = i - elif text == '可连接' or text == '可連接': - connectable_index = i - elif text == '上传' or text == '上傳': - uploaded_index = i - elif text == '下载' or text == '下載': - downloaded_index = i - elif text == '完成': - completed_index = i - else: - tds = tr.find_all('td') - peers.append({ - 'name': tds[name_index].get_text(), - 'connectable': True if tds[connectable_index].get_text() != '是' else False, - 'uploaded': tds[uploaded_index].get_text(), - 'downloaded': tds[downloaded_index].get_text(), - 'completed': float(tds[completed_index].get_text().strip('%')) / 100 - }) - except IndexError: - pass - except ValueError: - pass - return peers + try: + if hr_fn: + hr = hr_fn(detail_page) + else: + # selector: '#top > img' + hr_class = soup.find('h1', id='top').img['class'][0] + hr = (hr_class == 'hitandrun') + except Exception: + hr = False # 无HR soup = get_soup(peer_page.content) tables = soup.find_all('table', limit=2) try: - seeders = get_peers(tables[0]) + seeders = NexusPHP.get_peers(tables[0]) except IndexError: seeders = [] try: - leechers = get_peers(tables[1]) + leechers = NexusPHP.get_peers(tables[1]) except IndexError: leechers = [] - return discount, seeders, leechers + return discount, seeders, leechers, hr + + @staticmethod + def get_peers(table): + peers = [] + name_index = 0 + connectable_index = 1 + uploaded_index = 2 + downloaded_index = 4 + completed_index = 7 + for index, tr in enumerate(table.find_all('tr')): + try: + if index == 0: + tds = tr.find_all('td') + for i, td in enumerate(tds): + text = td.get_text() + if text == '用户' or text == '用戶': + name_index = i + elif text == '可连接' or text == '可連接': + connectable_index = i + elif text == '上传' or text == '上傳': + uploaded_index = i + elif text == '下载' or text == '下載': + downloaded_index = i + elif text == '完成': + completed_index = i + else: + tds = tr.find_all('td') + peers.append({ + 'name': tds[name_index].get_text(), + 'connectable': True if tds[connectable_index].get_text() != '是' else False, + 'uploaded': tds[uploaded_index].get_text(), + 'downloaded': tds[downloaded_index].get_text(), + 'completed': float(tds[completed_index].get_text().strip('%')) / 100 + }) + except Exception: + pass + return peers @staticmethod def _get_info(task, link, cookie): headers = { 'cookie': cookie, - 'accept-encoding': 'gzip, deflate', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/75.0.3770.142 Safari/537.36' } @@ -194,10 +217,42 @@ def _get_info(task, link, cookie): peer_url = link.replace('details.php', 'viewpeerlist.php', 1) peer_page = task.requests.get(peer_url, headers=headers, allow_redirects=False) # peer详情 - if detail_page.status_code == 302 or peer_page.status_code == 302: + if 'login' in detail_page.url or 'login' in peer_page.url: raise plugin.PluginError("Can't access the site. Your cookie may be wrong!") - return NexusPHP.info_from_page(detail_page, peer_page) + if 'chdbits' in link: + def discount_fn(page): + convert = { + 'pro_free': 'free', + 'pro_2up': '2x', + 'pro_free2up': '2xfree', + 'pro_30pctdown': '30%', + 'pro_50pctdown': '50%', + 'pro_50pctdown2up': '2x50%' + } + for key, value in convert.items(): + if key in page.text: + return value + return None + return NexusPHP.info_from_page(detail_page, peer_page, discount_fn) + if 'u2.dmhy' in link: + def discount_fn(page): + convert = { + 'pro_free': 'free', + 'pro_2up': '2x', + 'pro_free2up': '2xfree', + 'pro_30pctdown': '30%', + 'pro_50pctdown': '50%', + 'pro_50pctdown2up': '2x50%', + 'pro_custom': '2x' + } + for key, value in convert.items(): + if key in page.text: + return value + return None + return NexusPHP.info_from_page(detail_page, peer_page, discount_fn) + else: + return NexusPHP.info_from_page(detail_page, peer_page) @event('plugin.register') diff --git a/site.md b/site.md new file mode 100644 index 0000000..aa9d222 --- /dev/null +++ b/site.md @@ -0,0 +1,14 @@ +# 判断站点支持程度 +- 若发现日志输出大量none,可能该站点不支持,请联系开发者适配 +```bash +REJECTED: `XXX` by nexusphp plugin because none does not match discount +``` +- 该站点结构和其他站点区别较大,可能不支持 + +# 适配站点 +请联系开发者并提供以下信息: +- 站点名 +- Flexget相关输出日志 +- 站点关键HTML结构截图,只需要free信息附近的HTML代码 + +`注意:提供信息时注意passkey` \ No newline at end of file