Skip to content

Commit

Permalink
Merge pull request #46 from Rock-Candy-Tea/dev
Browse files Browse the repository at this point in the history
release 4.3.2
  • Loading branch information
hiltay authored Jun 14, 2022
2 parents 70cbb36 + 012b99f commit fc5afb5
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 122 deletions.
30 changes: 11 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

部署教程:[文档](https://fcircle-doc.js.cool/) | [备用地址](https://fcircle-doc.is-a.dev/)

⭐从4.1.3版本开始,一定要在配置项中配置友链页和获取策略
```
目前 release 4.3.1 版本
4.3.2 支持
- 支持 gitee 和 github 上的 issuse 友链获取
- 支持butterfly、volantis、matery、sakura、fluid、nexmoe、Yun、stun、stellar、next主题的友链和文章获取
- 支持feed订阅规则,如atom、rss等规则(支持wordpress类型的博客)
Expand All @@ -19,25 +18,18 @@
- 多种数据存储,提供leancloud,mysql,sqlite,mongodb存储方式
- 多种方式部署,提供github,server,docker部署方式
- 将api整合到主仓库
- 新增友链获取策略的common规则
- 新增友链获取策略的多种common规则
- 新增api方式的配置项友链
- 将额外友链页和环境变量友链统一为LINK,在配置文件中配置
- 提供一个简单的快速部署脚本
bug修复和改动:
- wordpress类型博客的时间格式问题
- butterfly主题友链页解析不再抓取背景图片了
- 修复了github和gitee对volantis主题的友链获取
- 屏蔽站点现在不计入失联数
- 修复了sakura主题和nexmoe主题偶尔报错的问题
- 现在可以获取Yun主题的外置JSON友链
- 优化了启动项配置
- feed订阅解析更加精准了
- 解决了docker和server定时任务运行爬虫报错的问题
- 文章超出当前时间的判断,逻辑优化与代码格式化
- 移除bs4依赖
- 移除旧订阅规则解析
- 修复butterfly的时间获取
- 额外友链页也可以配置获取策略
- 修复过期文章清除不生效的问题,解决mongodb空插入报错问题
最近改动:
- 添加mongodb workflow
- randomfriend和randompost两个接口支持随机N篇功能
- 新增lostfriends接口,用于快速查询失联友链
- 修复leancloud过期文章清理不生效的问题
- 添加自定义日志信息
- 修复leancloud接口中统计的数量和实际数量不同的问题
- 修复leancloud接口中创建时间和更新时间颠倒问题
```

73 changes: 63 additions & 10 deletions api/leancloudapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import requests
import leancloud
from hexo_circle_of_friends import settings
from hexo_circle_of_friends.utils.process_time import time_compare


def db_init():
Expand Down Expand Up @@ -71,10 +72,11 @@ def query_all(list, start: int = 0, end: int = -1, rule: str = "updated"):
return {"message": "rule error, please use 'created'/'updated'"}

rules = []
# list sort 是 稳定 的,这意味着当多个记录具有相同的键值时,将**保留其原始顺序**
if rule == "created":
rules.extend(["created", "updated"])
else:
rules.extend(["updated", "created"])
else:
rules.extend(["created", "updated"])
for r in rules:
try:
article_data_init.sort(key=lambda x: x[r], reverse=True)
Expand Down Expand Up @@ -114,7 +116,7 @@ def query_friend():
return friend_list_json


def query_random_friend():
def query_random_friend(num):
# Verify key
db_init()

Expand All @@ -133,10 +135,20 @@ def query_random_friend():
'avatar': item.get('firendimg')
}
friend_list_json.append(itemlist)
return random.choice(friend_list_json)
try:
if num < 1:
return {"message": "param 'num' error"}
elif num == 1:
return random.choice(friend_list_json)
elif num <= len(friend_list_json):
return random.sample(friend_list_json, k=num)
else:
return random.sample(friend_list_json, k=len(friend_list_json))
except:
return {"message": "not found"}


def query_random_post():
def query_random_post(num):
# Verify key
db_init()

Expand All @@ -162,7 +174,18 @@ def query_random_post():
article_data_init.sort(key=lambda x: x["updated"], reverse=True)
for item in article_data_init:
article_data.append(item)
return random.choice(article_data)
# return random.choice(article_data)
try:
if num < 1:
return {"message": "param 'num' error"}
elif num == 1:
return random.choice(article_data)
elif num <= len(article_data):
return random.sample(article_data, k=num)
else:
return random.sample(article_data, k=len(article_data))
except:
return {"message": "not found"}


def query_post(link, num, rule):
Expand Down Expand Up @@ -209,15 +232,14 @@ def query_post(link, num, rule):
if not author:
return {"message": "not found"}
article_num = len(article_data_init)
if num < 0 or num > min(article_num, 1000):
num = min(article_num, 1000)
api_json['statistical_data'] = {
"author": author,
"link": link,
"avatar": avatar,
"article_num": article_num
"article_num": num
}

if num < 0 or num > min(article_num, 1000):
num = min(article_num, 1000)
if rule != "created" and rule != "updated":
return {"message": "rule error, please use 'created'/'updated'"}
article_data_init.sort(key=lambda x: x[rule], reverse=True)
Expand All @@ -230,6 +252,37 @@ def query_post(link, num, rule):
return api_json


def query_lost_friends(days):
# 初始化数据库连接
db_init()
# 查询
Friendspoor = leancloud.Object.extend('friend_poor')
query = Friendspoor.query
query.descending('time')
query.limit(1000)
query.select('updated', 'author')
query_list = query.find()

Friendlist = leancloud.Object.extend('friend_list')
query_userinfo = Friendlist.query
query_userinfo.limit(1000)
query_userinfo.select('friendname', 'friendlink')
query_list_user = query_userinfo.find()
name_2_link_map = {user.get("friendname"): user.get("friendlink") for user in query_list_user}
lost_friends = {
"total_lost_num": 0,
"lost_friends": {}
}
for i in query_list:
if time_compare(i.get("updated"), days):
# 超过了指定天数
lost_friends_dict = lost_friends["lost_friends"]
if not lost_friends_dict.get(i.get("author")):
lost_friends["total_lost_num"] += 1
lost_friends["lost_friends"][i.get("author")] = name_2_link_map.get(i.get("author"))
return lost_friends


def query_post_json(jsonlink, list, start, end, rule):
# Verify key
db_init()
Expand Down
51 changes: 34 additions & 17 deletions api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
elif settings.DATABASE == "mongodb":
from api.mongodbapi import *

OUTDATE_CLEAN = settings.OUTDATE_CLEAN

app = FastAPI()

origins = [
Expand All @@ -37,61 +39,76 @@

@app.get("/all", tags=["API"], summary="返回完整统计信息")
def all(start: int = 0, end: int = -1, rule: str = "updated"):
'''返回数据库统计信息和文章信息列表
"""返回数据库统计信息和文章信息列表
- start: 文章信息列表从 按rule排序后的顺序 的开始位置
- end: 文章信息列表从 按rule排序后的顺序 的结束位置
- rule: 文章排序规则(创建时间/更新时间)
'''
"""
list = ['title', 'created', 'updated', 'link', 'author', 'avatar']
return query_all(list, start, end, rule)


@app.get("/friend", tags=["API"], summary="返回所有友链")
def friend():
'''返回数据库友链列表
'''
"""返回数据库友链列表
"""
return query_friend()


@app.get("/randomfriend", tags=["API"], summary="返回随机友链")
def random_friend():
'''随机返回一个友链信息
'''
return query_random_friend()
def random_friend(num: int = 1):
"""
随机返回num个友链信息:
- num=1,返回友链信息的字典
- num>1,返回包含num个友链信息字典的列表
"""
return query_random_friend(num)


@app.get("/randompost", tags=["API"], summary="返回随机文章")
def random_post():
'''随机返回一篇文章信息
'''
return query_random_post()
def random_post(num: int = 1):
"""
随机返回num篇文章信息:
- num=1,返回文章信息的字典
- num>1,返回包含num个文章信息字典的列表
"""
return query_random_post(num)


@app.get("/post", tags=["API"], summary="返回指定链接的所有文章")
def post(link: str = None, num: int = -1, rule: str = "created"):
'''返回指定链接的数据库内文章信息列表
"""返回指定链接的数据库内文章信息列表
- link: 链接地址
- num: 指定链接的文章信息列表 按rule排序后的顺序的前num篇
- rule: 文章排序规则(创建时间/更新时间)
'''
"""
return query_post(link, num, rule)

@app.get("/lostfriends", tags=["API"], summary="返回所有大于指定时间的友链信息")
def lost_friends(days: int = OUTDATE_CLEAN):
"""返回所有大于指定时间的友链信息,默认距离今天2个月以上(60天以上)判定为失联友链
days: 默认为60天,取自配置文件settings.py中的OUTDATE_CLEAN
"""
return query_lost_friends(days)


@app.get("/postjson", tags=["API"], summary="返回指定所有链接的所有文章")
def postjson(jsonlink: str, start: int = 0, end: int = -1, rule: str = "updated"):
'''获取公共库中指定链接列表的文章信息列表
"""获取公共库中指定链接列表的文章信息列表
- jsonlink: 友链链接json的cdn地址
- start: 文章信息列表从 按rule排序后的顺序 的开始位置
- end: 文章信息列表从 按rule排序后的顺序 的结束位置
- rule: 文章排序规则(创建时间/更新时间)
'''
"""
list = ['title', 'created', 'updated', 'link', 'author', 'avatar']
return query_post_json(jsonlink, list, start, end, rule)


@app.get("/version", tags=["version"], summary="返回版本信息")
async def version():
# status:0 不需要更新;status:1 需要更新 status:2 检查更新失败
"""版本检查
status:0 不需要更新;status:1 需要更新 status:2 检查更新失败
"""
api_json = {"status": 0}
if settings.VERSION:
try:
Expand Down
61 changes: 50 additions & 11 deletions api/mongodbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from urllib import parse
from hexo_circle_of_friends import settings
from pymongo import MongoClient
from hexo_circle_of_friends.utils.process_time import time_compare


def db_init():
Expand Down Expand Up @@ -74,27 +75,43 @@ def query_friend():
return friend_list_json


def query_random_friend():
def query_random_friend(num):
_, friend_db_collection = db_init()
friends = friend_db_collection.find({}, {"_id": 0, "createdAt": 0, "error": 0})
friends_num = friend_db_collection.count_documents({})
random_friend = friends[random.randint(0, friends_num - 1)]

return random_friend if random_friend else {"message": "not found"}
friends = list(friend_db_collection.find({}, {"_id": 0, "createdAt": 0, "error": 0}))
try:
if num < 1:
return {"message": "param 'num' error"}
elif num == 1:
return random.choice(friends)
elif num <= len(friends):
return random.sample(friends, k=num)
else:
return random.sample(friends, k=len(friends))
except:
return {"message": "not found"}


def query_random_post():
def query_random_post(num):
post_collection, _ = db_init()
posts = post_collection.find({}, {'_id': 0, "rule": 0, "createdAt": 0})
posts = list(post_collection.find({}, {'_id': 0, "rule": 0, "createdAt": 0}))
posts_num = post_collection.count_documents({})
random_post = posts[random.randint(0, posts_num - 1)]
return random_post if random_post else {"message": "not found"}
try:
if num < 1:
return {"message": "param 'num' error"}
elif num == 1:
return random.choice(posts)
elif num <= len(posts):
return random.sample(posts, k=num)
else:
return random.sample(posts, k=len(posts))
except:
return {"message": "not found"}


def query_post(link, num, rule):
post_collection, friend_db_collection = db_init()
if link is None:
friend = query_random_friend()
friend = query_random_friend(1)
domain = parse.urlsplit(friend.get("link")).netloc
else:
domain = parse.urlsplit(link).netloc
Expand All @@ -121,5 +138,27 @@ def query_post(link, num, rule):
return api_json


def query_lost_friends(days):
# 初始化数据库连接
post_collection, friend_db_collection = db_init()
# 查询
posts = list(post_collection.find({}, {'_id': 0, "rule": 0, "createdAt": 0, "created": 0, "avatar": 0, "link": 0, "title": 0}))
friends = list(friend_db_collection.find({}, {"_id": 0, "createdAt": 0, "error": 0, "avatar": 0}))
name_2_link_map = {user.get("name"): user.get("link") for user in friends}
lost_friends = {
"total_lost_num": 0,
"lost_friends": {}
}

for i in posts:
if time_compare(i.get("updated"), days):
# 超过了指定天数
lost_friends_dict = lost_friends["lost_friends"]
if not lost_friends_dict.get(i.get("author")):
lost_friends["total_lost_num"] += 1
lost_friends["lost_friends"][i.get("author")] = name_2_link_map.get(i.get("author"))
return lost_friends


def query_post_json(jsonlink, list, start, end, rule):
return {"message": "not found"}
Loading

0 comments on commit fc5afb5

Please sign in to comment.