add redis, new response

This commit is contained in:
BennyThink
2021-01-10 14:17:11 +08:00
parent eec57da15d
commit cc4c81b493
7 changed files with 106 additions and 81 deletions

View File

@@ -1,4 +1,4 @@
FROM python:alpine
FROM python:3.8-alpine
RUN apk update && apk add --no-cache tzdata alpine-sdk libxml2 libxslt-dev
COPY requirements.txt /requirements.txt

View File

@@ -1,16 +1,21 @@
# YYeTsBot
人人影视bot[戳我使用](https://t.me/yyets_bot) 此机器人长期维护,如果遇到问题可以发送报告给我。
# 使用说明
直接发送想要看的剧集名称就可以了可选分享网页或者链接ed2k和磁力链接
直接发送想要看的剧集名称就可以了可选分享网页或者链接ed2k和磁力链接
**由于译名的不同,建议输入部分译名,然后从列表中进行选择。**
# commands
```
start - 开始使用
help - 帮助
credits - 致谢
ping - 运行状态
```
# 截图
![](assets/1.jpg)
@@ -18,40 +23,54 @@ ping - 运行状态
![](assets/2.jpg)
# 部署方法
## 使用docker
```bash
docker run -d --restart=always -e TOKEN="TOKEN" bennythink/yyetsbot
```
根据情况,还可以 `-e USERNAME="1234"`USERNAME和PASSWORD是在人人影视的有效的用户名和密码
也可以自己构建docker image
```bash
docker build -t yyetsbot .
```
## 使用docker
参见 [这里](https://github.com/tgbot-collection/BotsRunner)
## 常规方式
### 1. 环境
推荐使用Python 3.6+
推荐使用Python 3.6+需要安装redis `apt install redis`根据个人情况可以使用virtualenv
```bash
pip install -r requirements.py
```
### 2. 配置TOKEN
修改`config.py`把TOKEN修改为你的bot token, USERNAME和PASSWORD是在人人影视的有效的用户名和密码
修改`config.py`,根据需求修改如下配置项
* TOKENbot token
* USERNAMEUSERNAME和PASSWORD是在人人影视的有效的用户名和密码
* PASSWORD USERNAME和PASSWORD是在人人影视的有效的用户名和密码
* PROXY :是否需要使用代理 格式 `socks5://userproxy:password@proxy_address:port`
* MAINTAINER维护者的Telegram UserID
* REDISredis的地址一般为localhost
也可以使用环境变量,如 `export TOKEN="1234"`
### 3. 运行
```bash
python /path/to/YYeTsBot/bot.py
```
### 4. systemd 单元文件
参考 `yyets.service`
# Help
- [ ] test case...
# Credits
* [人人影视](http://www.zmz2019.com/)
* [追新番](http://www.zhuixinfan.com/main.php)
* [FIX字幕侠](http://www.zimuxia.cn/)
* [磁力下载站](http://oabt005.com/home.html)
# License
[MIT](LICENSE)

74
bot.py
View File

@@ -9,6 +9,8 @@ import time
import re
import os
import logging
import json
import tempfile
from urllib.parse import quote_plus
@@ -17,7 +19,7 @@ from telebot import types, apihelper
from tgbot_ping import get_runtime
from html_request import get_search_html, analyse_search_html, get_detail_page
from utils import save_dump, upsert, get
from utils import save_dump, save_to_cache, get_from_cache
from config import PROXY, TOKEN, SEARCH_URL, MAINTAINER
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(filename)s [%(levelname)s]: %(message)s')
@@ -111,14 +113,13 @@ def send_search(message):
bot.send_sticker(message.chat.id, sti)
return
logging.info('Receiving message about %s from user %s(%s)', name, message.chat.username,
message.chat.id)
logging.info('Receiving message about %s from user %s(%s)', name, message.chat.username, message.chat.id)
html = get_search_html(name)
result = analyse_search_html(html)
markup = types.InlineKeyboardMarkup()
for url, detail in result.items():
btn = types.InlineKeyboardButton(detail['name'], callback_data=url)
btn = types.InlineKeyboardButton(detail['name'], callback_data="choose%s" % url)
markup.add(btn)
if result:
@@ -145,59 +146,46 @@ def send_search(message):
save_dump(content)
@bot.callback_query_handler(func=lambda call: 'resource' in call.data)
@bot.callback_query_handler(func=lambda call: re.findall(r"choose(\S*)", call.data))
def choose_link(call):
bot.send_chat_action(call.message.chat.id, 'typing')
resource_url = call.data
link = get_detail_page(resource_url)
upsert(call.id, link)
# call.data is url, http://www.rrys2020.com/resource/36588
resource_url = re.findall(r"choose(\S*)", call.data)[0]
link = get_from_cache(resource_url)
if not link:
link = get_detail_page(resource_url)
save_to_cache(resource_url, link)
markup = types.InlineKeyboardMarkup()
btn1 = types.InlineKeyboardButton("分享页面", callback_data="share%s" % call.id)
btn2 = types.InlineKeyboardButton("继续点按钮", callback_data="select%s" % call.id)
btn1 = types.InlineKeyboardButton("分享页面", callback_data="share%s" % resource_url)
btn2 = types.InlineKeyboardButton("我全都要", callback_data="all%s" % resource_url)
markup.add(btn1, btn2)
bot.send_message(call.message.chat.id, "想要分享页面,还是继续点击按钮", reply_markup=markup)
bot.send_message(call.message.chat.id, "想要分享页面,还是我全都要?", reply_markup=markup)
@bot.callback_query_handler(func=lambda call: re.findall(r"share(\d*)", call.data))
@bot.callback_query_handler(func=lambda call: re.findall(r"share(\S*)", call.data))
def share_page(call):
bot.send_chat_action(call.message.chat.id, 'typing')
cid = re.findall(r"share(\d*)", call.data)[0]
result = get(cid)
resource_url = re.findall(r"share(\S*)", call.data)[0]
result = get_from_cache(resource_url)
bot.send_message(call.message.chat.id, result['share'])
@bot.callback_query_handler(func=lambda call: re.findall(r"select(\d*)", call.data))
def select_episode(call):
@bot.callback_query_handler(func=lambda call: re.findall(r"all(\S*)", call.data))
def all_episode(call):
# just send a file
bot.send_chat_action(call.message.chat.id, 'typing')
cid = re.findall(r"select(\d*)", call.data)[0]
result = get(cid)
markup = types.InlineKeyboardMarkup()
resource_url = re.findall(r"all(\S*)", call.data)[0]
result = get_from_cache(resource_url)
if not result['rss']:
btn = types.InlineKeyboardButton("点击打开分享网站", url=result['share'])
markup.add(btn)
bot.send_message(call.message.chat.id, "哎呀呀,这是个电影,恐怕没得选吧!", reply_markup=markup)
else:
for guid, detail in result['rss'].items():
btn = types.InlineKeyboardButton(detail['title'], callback_data=f"cid{cid}guid{guid}")
markup.add(btn)
bot.send_message(call.message.chat.id, "选一集吧!", reply_markup=markup)
with tempfile.NamedTemporaryFile(mode='wb+', prefix=result["cnname"], suffix=".txt") as tmp:
bytes_data = json.dumps(result["all"], ensure_ascii=False, indent=4).encode('u8')
tmp.write(bytes_data)
@bot.callback_query_handler(func=lambda call: re.findall(r"cid(\d*)guid(.*)", call.data))
def send_link(call):
bot.send_chat_action(call.message.chat.id, 'typing')
data = re.findall(r"cid(\d*)guid(.*)", call.data)[0]
cid, guid = data[0], data[1]
links = get(cid)['rss'][guid]
ed2k, magnet, pan = "`{}`".format(links['ed2k']), "`{}`".format(links['magnet']), "`{}`".format(links['pan'])
bot.send_message(call.message.chat.id, f"{links['title']}的下载资源如下")
if ed2k != "``":
bot.send_message(call.message.chat.id, ed2k, parse_mode='markdown')
if magnet != "``":
bot.send_message(call.message.chat.id, magnet, parse_mode='markdown')
if pan != "``":
bot.send_message(call.message.chat.id, pan, parse_mode='markdown')
bot.send_chat_action(call.message.chat.id, 'upload_document')
with open(tmp.name, "rb") as f:
bot.send_document(call.message.chat.id, f)
@bot.callback_query_handler(func=lambda call: call.data == 'fix')

View File

@@ -9,14 +9,19 @@ import os
BASE_URL = "http://www.rrys2020.com"
LOGIN_URL = "http://www.rrys2020.com/user/login"
GET_USER = "http://www.rrys2020.com/user/login/getCurUserTopInfo"
# rss is unavailable as of 2021.01.10
RSS_URL = "http://rss.rrys.tv/rss/feed/{id}"
RESOURCE_SCORE = "http://www.rrys2020.com/resource/getScore" # post rid=38000
SEARCH_URL = "http://www.rrys2020.com/search?keyword={kw}&type=resource"
AJAX_LOGIN = "http://www.rrys2020.com/User/Login/ajaxLogin"
SHARE_URL = "http://www.rrys2020.com/resource/ushare"
SHARE_WEB = "http://got002.com/resource.html?code={code}"
# http://got002.com/api/v1/static/resource/detail?code=9YxN91
SHARE_API = "http://got002.com/api/v1/static/resource/detail?code={code}"
TOKEN = os.environ.get("TOKEN") or "TOKEN"
USERNAME = os.environ.get("USERNAME") or "USERNAME"
PASSWORD = os.environ.get("PASSWORD") or "password"
PROXY = os.environ.get("PROXY")
MAINTAINER = os.environ.get("MAINTAINER")
REDIS = os.environ.get("REDIS") or "redis"

View File

@@ -10,7 +10,7 @@ import requests
import feedparser
from bs4 import BeautifulSoup
from config import SEARCH_URL, GET_USER, RSS_URL, BASE_URL, SHARE_WEB, SHARE_URL, RESOURCE_SCORE
from config import SEARCH_URL, GET_USER, RSS_URL, BASE_URL, SHARE_WEB, SHARE_URL, RESOURCE_SCORE, SHARE_API
from utils import load_cookies, cookie_file, login
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(filename)s [%(levelname)s]: %(message)s')
@@ -32,15 +32,22 @@ def get_search_html(kw: str) -> str:
return r.text
def get_detail_page(url: str):
def get_detail_page(url: str) -> dict:
logging.info("loading detail page %s", url)
share_link, api_res = analysis_share_page(url)
cnname = api_res["data"]["info"]["cnname"]
logging.info("Share page complete for %s", cnname)
logging.info("Getting rss...")
rss_url = RSS_URL.format(id=url.split("/")[-1])
rss_result = analyse_rss(rss_url)
logging.info("RSS complete...")
logging.info("loading detail page %s", url)
share_link = analysis_share_page(url)
# get name from here...
if not rss_result:
rss_result = api_res
return {"rss": rss_result, "share": share_link}
return {"all": rss_result, "share": share_link, "cnname": cnname}
def analyse_search_html(html: str) -> dict:
@@ -70,7 +77,7 @@ def analyse_rss(feed_url: str) -> dict:
return result
def analysis_share_page(detail_url: str) -> str:
def analysis_share_page(detail_url: str) -> (str, dict):
rid = detail_url.split('/')[-1]
logging.info("rid is %s", rid)
@@ -79,7 +86,10 @@ def analysis_share_page(detail_url: str) -> str:
logging.info("Share code is %s", share_code)
share_url = SHARE_WEB.format(code=share_code)
logging.info("Share url %s", share_url)
return share_url
# get api response
api_response = s.get(SHARE_API.format(code=share_code)).json()
return share_url, api_response
def get_score(rid: str) -> float:

View File

@@ -4,4 +4,5 @@ beautifulsoup4
lxml
feedparser
pysocks
tgbot-ping
tgbot-ping
redis

View File

@@ -4,36 +4,38 @@
__author__ = 'Benny <benny.think@gmail.com>'
import dbm
import os
import sys
import pickle
import json
import logging
import requests
import redis
from config import AJAX_LOGIN, USERNAME, PASSWORD
from config import AJAX_LOGIN, USERNAME, PASSWORD, REDIS
r = redis.StrictRedis(host=REDIS, decode_responses=True)
db_path = os.path.join(os.path.dirname(__file__), 'data', 'yyets.dbm')
db = dbm.open(db_path, 'c')
cookie_file = os.path.join(os.path.dirname(__file__), 'data', 'cookies.dump')
def batch_upsert(data: dict) -> None:
for k in data:
upsert(k, data[k])
def save_to_cache(url: str, value: dict) -> None:
data = json.dumps(value, ensure_ascii=False)
r.set(url, data, ex=3600 * 12)
def upsert(key: str, value: dict) -> None:
db[key] = json.dumps(value, ensure_ascii=False)
def get_from_cache(url: str) -> dict:
logging.info("Reading data from cache %s", url)
from html_request import get_detail_page
def get(key: str) -> dict:
return json.loads(db.get(key, '{}'))
def delete(key: str) -> None:
del db[key]
data = r.get(url)
if data:
logging.info("cache hit")
return json.loads(data)
else:
logging.info("cache miss")
save_to_cache(url, get_detail_page(url))
return get_from_cache(url)
def save_dump(err):