mirror of
https://github.com/tgbot-collection/YYeTsBot.git
synced 2025-11-25 03:15:05 +08:00
comment search
This commit is contained in:
176
API.md
176
API.md
@@ -11,12 +11,15 @@
|
||||
- [x] API变更:登录时需要验证码
|
||||
- [x] API变更:like API变更 PATCH `/api/user/` --> PATCH `/api/like/`
|
||||
- [x] 删除评论(admin only)
|
||||
- [x] ME:搜索API返回变更:目前包含了评论的结果,使用 `type`区分
|
||||
- [ ] 搜索页面,通过评论ID,只显示该评论
|
||||
- [ ] **独立公告和最近更新到新的页面**
|
||||
- [ ] **对评论的反应**
|
||||
- [ ] **分类**
|
||||
- [ ] 添加下载地址到已有资源
|
||||
- [ ] 新增资源
|
||||
- [ ] 删除资源、删除已有资源的下载
|
||||
- [ ] 对评论的反应
|
||||
- [ ] 更改用户信息(添加邮箱)
|
||||
- [ ] 分类
|
||||
- [ ] 评论通知(浏览器通知,暂时隐藏了)
|
||||
|
||||
# BE
|
||||
@@ -46,71 +49,119 @@
|
||||
|
||||
## 搜索
|
||||
|
||||
同时搜索资源和评论,会以type字段区分,评论会额外返回 `comment_id`(能根据这个ID过滤评论最好了)
|
||||
|
||||
* GET `/api/resource?keyword=逃避`
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"data": {
|
||||
"info": {
|
||||
"id": 34812,
|
||||
"cnname": "逃避可耻却有用",
|
||||
"enname": "NIGERUHA HAJIDAGA YAKUNITATSU",
|
||||
"aliasname": "逃避虽可耻但有用 / 雇佣妻子(港) / 月薪娇妻(台) / 逃跑是可耻但是有用 / 逃避虽可耻但很有用 / 逃避可耻但有用",
|
||||
"channel": "tv",
|
||||
"channel_cn": "日剧",
|
||||
"area": "日本",
|
||||
"show_type": "",
|
||||
"expire": "1610399344",
|
||||
"views": 1201,
|
||||
"year": [
|
||||
2016,
|
||||
2017,
|
||||
2021
|
||||
]
|
||||
}
|
||||
}
|
||||
"id": 10733,
|
||||
"cnname": "权力的游戏",
|
||||
"enname": "Game of Thrones",
|
||||
"aliasname": "冰与火之歌 / 权力的游戏下载 / 权利的游戏 / 冰火",
|
||||
"channel": "tv",
|
||||
"channel_cn": "美剧",
|
||||
"area": "美国",
|
||||
"show_type": "",
|
||||
"expire": "1610372082",
|
||||
"views": 34,
|
||||
"year": [
|
||||
2011
|
||||
],
|
||||
"type": "🎦"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"info": {
|
||||
"id": 29540,
|
||||
"cnname": "无法逃避",
|
||||
"enname": "Inescapable",
|
||||
"aliasname": "无法避免",
|
||||
"channel": "movie",
|
||||
"channel_cn": "电影",
|
||||
"area": "加拿大",
|
||||
"show_type": "",
|
||||
"expire": "1610396227",
|
||||
"views": 1,
|
||||
"year": [
|
||||
2012
|
||||
]
|
||||
}
|
||||
}
|
||||
"id": 35844,
|
||||
"cnname": "权力的游戏:征服与反抗",
|
||||
"enname": "Game of Thrones: Conquest and Rebellion",
|
||||
"aliasname": "",
|
||||
"channel": "movie",
|
||||
"channel_cn": "电影",
|
||||
"area": "美国",
|
||||
"show_type": "",
|
||||
"expire": "1610399882",
|
||||
"views": 1,
|
||||
"year": [
|
||||
2017
|
||||
],
|
||||
"type": "🎦"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"info": {
|
||||
"id": 37089,
|
||||
"cnname": "逃避者",
|
||||
"enname": "Shirkers",
|
||||
"aliasname": "",
|
||||
"channel": "movie",
|
||||
"channel_cn": "电影",
|
||||
"area": "美国",
|
||||
"show_type": "",
|
||||
"expire": "1610400512",
|
||||
"views": 0,
|
||||
"year": [
|
||||
2018
|
||||
]
|
||||
}
|
||||
}
|
||||
"cnname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P......",
|
||||
"enname": "👉︎👉︎👉︎ happy69",
|
||||
"aliasname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P」,你可以不限速下载🚀\n复制这段内容打开「阿里云盘」App 即可获取\n链接:https://www.aliyundrive.com/s/zf3WotW6oiC",
|
||||
"channel_cn": "happy69",
|
||||
"type": "💬",
|
||||
"id": 233,
|
||||
"comment_id": "614bfc698510b2408c1926b5"
|
||||
},
|
||||
{
|
||||
"cnname": "我用阿里云盘分享了「权力的游戏人人影视版」,你可以不限速下载......",
|
||||
"enname": "👉︎👉︎👉︎ jadydou",
|
||||
"aliasname": "我用阿里云盘分享了「权力的游戏人人影视版」,你可以不限速下载🚀\n复制这段内容打开「阿里云盘」App 即可获取\n链接:https://www.aliyundrive.com/s/WDsKgqyxGps",
|
||||
"channel_cn": "jadydou",
|
||||
"type": "💬",
|
||||
"id": 10733,
|
||||
"comment_id": "6147fa307af3626caa5523a1"
|
||||
},
|
||||
{
|
||||
"cnname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P......",
|
||||
"enname": "👉︎👉︎👉︎ 18103421965",
|
||||
"aliasname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P」,你可以不限速下载🚀\n复制这段内容打开「阿里云盘」App 即可获取\n链接:https://www.aliyundrive.com/s/A5qPZoP2Jrt",
|
||||
"channel_cn": "18103421965",
|
||||
"type": "💬",
|
||||
"id": 10733,
|
||||
"comment_id": "614798052afd8de53754bedb"
|
||||
},
|
||||
{
|
||||
"cnname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P......",
|
||||
"enname": "👉︎👉︎👉︎ 18103421965",
|
||||
"aliasname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P」,你可以不限速下载🚀\n复制这段内容打开「阿里云盘」App 即可获取\n链接:https://www.aliyundrive.com/s/A5qPZoP2Jrt",
|
||||
"channel_cn": "18103421965",
|
||||
"type": "💬",
|
||||
"id": 10914,
|
||||
"comment_id": "614797cd7af3626caa54cf47"
|
||||
},
|
||||
{
|
||||
"cnname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P......",
|
||||
"enname": "👉︎👉︎👉︎ kevinluo",
|
||||
"aliasname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P」,你可以不限速下载🚀\n复制这段内容打开「阿里云盘」App 即可获取\n链接:https://www.aliyundrive.com/s/o58i7s3dcYJ",
|
||||
"channel_cn": "kevinluo",
|
||||
"type": "💬",
|
||||
"id": 10733,
|
||||
"comment_id": "6146458e2afd8de537529caa"
|
||||
},
|
||||
{
|
||||
"cnname": "网盘目录 Game.of.Thrones.权力的游戏.txt......",
|
||||
"enname": "👉︎👉︎👉︎ zzzyusa",
|
||||
"aliasname": "网盘目录 Game.of.Thrones.权力的游戏.txt: https://url90.ctfile.com/f/2536190-513324961-96c675 (访问密码:5413)",
|
||||
"channel_cn": "zzzyusa",
|
||||
"type": "💬",
|
||||
"id": 10733,
|
||||
"comment_id": "613cbca484bab96c4fa32aef"
|
||||
},
|
||||
{
|
||||
"cnname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P......",
|
||||
"enname": "👉︎👉︎👉︎ 牛啊牛啊",
|
||||
"aliasname": "我用阿里云盘分享了「权力的游戏.1-8季无删减版.1080P」,你可以不限速下载https://www.aliyundrive.com/s/NPqweJ6GL6c",
|
||||
"channel_cn": "牛啊牛啊",
|
||||
"type": "💬",
|
||||
"id": 10733,
|
||||
"comment_id": "61363b5d2f17def162a66c26"
|
||||
},
|
||||
{
|
||||
"cnname": "<reply value=\"60ef0913898cc061......",
|
||||
"enname": "👉︎👉︎👉︎ Benny",
|
||||
"aliasname": "<reply value=\"60ef0913898cc06157c5847c\">@408188289@qq.com</reply>目前Resilio Sync 只有黑寡妇这个有,别的我都没做种……😂权力的游戏的话,我硬盘里有,等哪天我有空更新下吧",
|
||||
"channel_cn": "Benny",
|
||||
"type": "💬",
|
||||
"id": 233,
|
||||
"comment_id": "60efb14c898cc06157c617a7"
|
||||
}
|
||||
]
|
||||
],
|
||||
"extra": []
|
||||
}
|
||||
```
|
||||
|
||||
@@ -496,6 +547,7 @@ response
|
||||
分页,支持URL参数:
|
||||
|
||||
* resource_id: 资源id,id为233是留言板,id为-1会返回最新评论
|
||||
* comment_id: 指定该参数,会只返回这条评论
|
||||
* size: 每页评论数量,默认5
|
||||
* page: 当前页,默认1
|
||||
* inner_size: 内嵌评论数量,默认5
|
||||
@@ -562,6 +614,18 @@ response
|
||||
}
|
||||
```
|
||||
|
||||
## 搜索评论
|
||||
|
||||
* GET `/api/comment/search`
|
||||
|
||||
分页,支持URL参数:
|
||||
|
||||
* size: 每页评论数量,默认5
|
||||
* page: 当前页,默认1
|
||||
* keyword: 关键字
|
||||
|
||||
返回值与获取评论相同
|
||||
|
||||
## 子评论分页
|
||||
|
||||
* GET `/api/comment/child`
|
||||
|
||||
2
YYeTsFE
2
YYeTsFE
Submodule YYeTsFE updated: ec00c3ee0b...d96a4610aa
@@ -182,7 +182,11 @@ class CommentMongoResource(CommentResource, Mongo):
|
||||
def get_comment(self, resource_id: int, page: int, size: int, **kwargs) -> dict:
|
||||
self.inner_page = kwargs.get("inner_page", 1)
|
||||
self.inner_size = kwargs.get("inner_size", 5)
|
||||
comment_id = kwargs.get("comment_id")
|
||||
|
||||
condition = {"resource_id": resource_id, "deleted_at": {"$exists": False}, "type": {"$ne": "child"}}
|
||||
if comment_id:
|
||||
condition.update(_id=ObjectId(comment_id))
|
||||
|
||||
count = self.db["comment"].count_documents(condition)
|
||||
data = self.db["comment"].find(condition, self.projection) \
|
||||
@@ -361,26 +365,39 @@ class CommentNewestMongoResource(CommentNewestResource, CommentMongoResource, Mo
|
||||
self.page = 1
|
||||
self.size = 5
|
||||
self.projection = {"ip": False, "parent_id": False, "children": False}
|
||||
self.condition = {"deleted_at": {"$exists": False}}
|
||||
self.condition: "dict" = {"deleted_at": {"$exists": False}}
|
||||
|
||||
def get_comment(self, page: int, size: int) -> dict:
|
||||
def get_comment(self, page: int, size: int, keyword="") -> dict:
|
||||
# ID,时间,用户名,用户组,资源名,资源id
|
||||
condition = {"deleted_at": {"$exists": False}}
|
||||
count = self.db["comment"].count_documents(condition)
|
||||
data = self.db["comment"].find(condition, self.projection) \
|
||||
count = self.db["comment"].count_documents(self.condition)
|
||||
data = self.db["comment"].find(self.condition, self.projection) \
|
||||
.sort("_id", pymongo.DESCENDING).limit(size).skip((page - 1) * size)
|
||||
data = list(data)
|
||||
self.convert_objectid(data)
|
||||
self.get_user_group(data)
|
||||
for i in data:
|
||||
resource_id = i.get("resource_id", 233)
|
||||
res = self.db["yyets"].find_one({"data.info.id": resource_id})
|
||||
i["cnname"] = res["data"]["info"]["cnname"]
|
||||
self.extra_info(data)
|
||||
return {
|
||||
"data": data,
|
||||
"count": count,
|
||||
}
|
||||
|
||||
def extra_info(self, data):
|
||||
for i in data:
|
||||
resource_id = i.get("resource_id", 233)
|
||||
res = self.db["yyets"].find_one({"data.info.id": resource_id})
|
||||
if res:
|
||||
i["cnname"] = res["data"]["info"]["cnname"]
|
||||
|
||||
|
||||
class CommentSearchMongoResource(CommentNewestMongoResource):
|
||||
|
||||
def get_comment(self, page: int, size: int, keyword="") -> dict:
|
||||
self.condition.update(content={'$regex': f'.*{keyword}.*', "$options": "-i"})
|
||||
return super(CommentSearchMongoResource, self).get_comment(page, size, keyword)
|
||||
|
||||
def extra_info(self, data):
|
||||
pass
|
||||
|
||||
|
||||
class GrafanaQueryMongoResource(GrafanaQueryResource, Mongo):
|
||||
def get_grafana_data(self, date_series) -> str:
|
||||
@@ -477,11 +494,14 @@ class ResourceMongoResource(ResourceResource, Mongo):
|
||||
return data
|
||||
|
||||
def search_resource(self, keyword: str) -> dict:
|
||||
final = []
|
||||
returned = {}
|
||||
|
||||
projection = {'_id': False,
|
||||
'data.info': True,
|
||||
}
|
||||
|
||||
data = self.db["yyets"].find({
|
||||
resource_data = self.db["yyets"].find({
|
||||
"$or": [
|
||||
{"data.info.cnname": {'$regex': f'.*{keyword}.*', "$options": "-i"}},
|
||||
{"data.info.enname": {'$regex': f'.*{keyword}.*', "$options": "-i"}},
|
||||
@@ -489,10 +509,30 @@ class ResourceMongoResource(ResourceResource, Mongo):
|
||||
]},
|
||||
projection
|
||||
)
|
||||
data = list(data)
|
||||
returned = {}
|
||||
if data:
|
||||
returned = dict(data=data)
|
||||
|
||||
for item in resource_data:
|
||||
item["data"]["info"]["type"] = "🎦"
|
||||
final.append(item["data"]["info"])
|
||||
|
||||
# get comment
|
||||
r = CommentSearchMongoResource().get_comment(1, 100, keyword)
|
||||
c_search = []
|
||||
for c in r.get("data", []):
|
||||
cnname = c["content"][:30] + "......"
|
||||
enname = f'👉︎👉︎👉︎ {c["username"]}'
|
||||
channel_cn = c["username"]
|
||||
aliasname = c["content"]
|
||||
resource_id = c["resource_id"]
|
||||
c_search.append(
|
||||
dict(
|
||||
cnname=cnname, enname=enname, aliasname=aliasname, channel_cn=channel_cn,
|
||||
type="💬", id=resource_id, comment_id=c["id"]
|
||||
)
|
||||
)
|
||||
final.extend(c_search)
|
||||
|
||||
if final:
|
||||
returned = dict(data=final)
|
||||
returned["extra"] = []
|
||||
else:
|
||||
extra = self.fansub_search(ZimuxiaOnline.__name__, keyword) or \
|
||||
@@ -975,7 +1015,7 @@ class ResourceLatestMongoResource(ResourceLatestResource, Mongo):
|
||||
projection = {"_id": False, "status": False, "info": False}
|
||||
episode_data = {}
|
||||
for res in tqdm(col.find(projection=projection), total=col.count()):
|
||||
for season in res["data"]["list"]:
|
||||
for season in res["data"].get("list",[]):
|
||||
for item in season["items"].values():
|
||||
for single in item:
|
||||
ts = single["dateline"]
|
||||
|
||||
@@ -174,7 +174,7 @@ class CommentChildResource:
|
||||
|
||||
|
||||
class CommentNewestResource:
|
||||
def get_comment(self, page: int, size: int) -> dict:
|
||||
def get_comment(self, page: int, size: int, keyword=None) -> dict:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -358,10 +358,16 @@ class CommentHandler(BaseHandler):
|
||||
page = int(self.get_argument("page", "1"))
|
||||
inner_size = int(self.get_argument("inner_size", "5"))
|
||||
inner_page = int(self.get_argument("inner_page", "1"))
|
||||
comment_id = self.get_argument("comment_id", None)
|
||||
|
||||
if not resource_id:
|
||||
self.set_status(HTTPStatus.BAD_REQUEST)
|
||||
return {"status": False, "message": "请提供resource id"}
|
||||
comment_data = self.instance.get_comment(resource_id, page, size, inner_size=inner_size, inner_page=inner_page)
|
||||
comment_data = self.instance.get_comment(
|
||||
resource_id, page, size,
|
||||
inner_size=inner_size, inner_page=inner_page,
|
||||
comment_id=comment_id
|
||||
)
|
||||
self.hide_phone((comment_data["data"]))
|
||||
return comment_data
|
||||
|
||||
@@ -490,6 +496,27 @@ class CommentNewestHandler(CommentHandler):
|
||||
self.write(resp)
|
||||
|
||||
|
||||
class CommentSearchHandler(CommentHandler):
|
||||
class_name = f"CommentSearch{adapter}Resource"
|
||||
|
||||
# from Mongo import CommentNewestResource
|
||||
# instance = CommentNewestResource()
|
||||
|
||||
@run_on_executor()
|
||||
def search_comment(self):
|
||||
size = int(self.get_argument("size", "5"))
|
||||
page = int(self.get_argument("page", "1"))
|
||||
keyword = self.get_argument("keyword", "")
|
||||
comment_data = self.instance.get_comment(page, size, keyword)
|
||||
self.hide_phone((comment_data["data"]))
|
||||
return comment_data
|
||||
|
||||
@gen.coroutine
|
||||
def get(self):
|
||||
resp = yield self.search_comment()
|
||||
self.write(resp)
|
||||
|
||||
|
||||
class AnnouncementHandler(BaseHandler):
|
||||
class_name = f"Announcement{adapter}Resource"
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import os
|
||||
import platform
|
||||
|
||||
import pytz
|
||||
import tornado.autoreload
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from tornado import httpserver, ioloop, options, web
|
||||
from tornado.log import enable_pretty_logging
|
||||
@@ -19,10 +20,10 @@ from tornado.log import enable_pretty_logging
|
||||
from handler import (AnnouncementHandler, BlacklistHandler, CaptchaHandler,
|
||||
CategoryHandler, CommentChildHandler, CommentHandler,
|
||||
CommentNewestHandler, CommentReactionHandler,
|
||||
DBDumpHandler, DoubanHandler, DoubanReportHandler,
|
||||
GrafanaIndexHandler, GrafanaQueryHandler,
|
||||
GrafanaSearchHandler, IndexHandler, LikeHandler,
|
||||
MetricsHandler, NameHandler, NotFoundHandler,
|
||||
DBDumpHandler, DoubanHandler,
|
||||
DoubanReportHandler, GrafanaIndexHandler,
|
||||
GrafanaQueryHandler, GrafanaSearchHandler, IndexHandler,
|
||||
LikeHandler, MetricsHandler, NameHandler, NotFoundHandler,
|
||||
NotificationHandler, ResourceHandler,
|
||||
ResourceLatestHandler, TopHandler, UserEmailHandler,
|
||||
UserHandler)
|
||||
@@ -80,8 +81,9 @@ class RunServer:
|
||||
def run_server(port, host):
|
||||
tornado_server = httpserver.HTTPServer(RunServer.application, xheaders=True)
|
||||
tornado_server.bind(port, host)
|
||||
if platform.uname().system == "Windows":
|
||||
if platform.uname().system in ("Windows", "Darwin"):
|
||||
tornado_server.start(1)
|
||||
tornado.autoreload.start()
|
||||
else:
|
||||
tornado_server.start(0)
|
||||
|
||||
@@ -98,7 +100,7 @@ if __name__ == "__main__":
|
||||
scheduler = BackgroundScheduler(timezone=timez)
|
||||
scheduler.add_job(OtherMongoResource().reset_top, 'cron', hour=0, minute=0, day=1)
|
||||
scheduler.add_job(sync_douban, 'cron', hour=0, minute=0, day=1)
|
||||
scheduler.add_job(ResourceLatestMongoResource().refresh_latest_resource, 'cron', minute=0)
|
||||
# scheduler.add_job(ResourceLatestMongoResource().refresh_latest_resource, 'cron', hour=1)
|
||||
scheduler.start()
|
||||
options.define("p", default=8888, help="running port", type=int)
|
||||
options.define("h", default='127.0.0.1', help="listen address", type=str)
|
||||
|
||||
Reference in New Issue
Block a user