diff --git a/deploy.sh b/deploy.sh index 4105e35..b5bb679 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,2 +1,2 @@ #!/bin/bash -nohup python server.py > grab.log 2>&1 & +nohup python3 server.py > grab.log 2>&1 & diff --git a/friend_circle_lite/__pycache__/__init__.cpython-311.pyc b/friend_circle_lite/__pycache__/__init__.cpython-311.pyc index 995bb7a..a8eadd5 100644 Binary files a/friend_circle_lite/__pycache__/__init__.cpython-311.pyc and b/friend_circle_lite/__pycache__/__init__.cpython-311.pyc differ diff --git a/friend_circle_lite/__pycache__/get_info.cpython-311.pyc b/friend_circle_lite/__pycache__/get_info.cpython-311.pyc index ead2e1a..f4f17c4 100644 Binary files a/friend_circle_lite/__pycache__/get_info.cpython-311.pyc and b/friend_circle_lite/__pycache__/get_info.cpython-311.pyc differ diff --git a/friend_circle_lite/get_info.py b/friend_circle_lite/get_info.py index 8657b31..235fb92 100644 --- a/friend_circle_lite/get_info.py +++ b/friend_circle_lite/get_info.py @@ -207,6 +207,7 @@ def fetch_and_process_data(json_url, count=5): error_friends = 0 total_articles = 0 article_data = [] + error_friends_info = [] with ThreadPoolExecutor(max_workers=10) as executor: future_to_friend = { @@ -224,9 +225,11 @@ def fetch_and_process_data(json_url, count=5): total_articles += len(result['articles']) else: error_friends += 1 + error_friends_info.append(friend) except Exception as e: print(f"处理 {friend} 时发生错误: {e}") error_friends += 1 + error_friends_info.append(friend) result = { 'statistical_data': { @@ -242,7 +245,7 @@ def fetch_and_process_data(json_url, count=5): print("数据处理完成") print("总共有 %d 位朋友,其中 %d 位博客可访问,%d 位博客无法访问" % (total_friends, active_friends, error_friends)) - return result + return result, error_friends_info def sort_articles_by_time(data): """ diff --git a/grab.log b/grab.log new file mode 100644 index 0000000..33c61ed --- /dev/null +++ b/grab.log @@ -0,0 +1,3 @@ +2024-07-22 10:21:56,649 - INFO - ʼץȡ... +2024-07-22 10:21:56,653 - INFO - ڴ https://blog.qyliu.top/friend.json лȡÿͻȡ 5 ƪ +2024-07-22 10:22:32,855 - INFO - ץȡɹ diff --git a/run.py b/run.py index ad9fc80..c3ed6a2 100644 --- a/run.py +++ b/run.py @@ -15,7 +15,7 @@ if config["spider_settings"]["enable"]: json_url = config['spider_settings']['json_url'] article_count = config['spider_settings']['article_count'] print("正在从 {json_url} 中获取,每个博客获取 {article_count} 篇文章".format(json_url=json_url, article_count=article_count)) - result = fetch_and_process_data(json_url=json_url, count=article_count) + result, _ = fetch_and_process_data(json_url=json_url, count=article_count) sorted_result = sort_articles_by_time(result) with open("all.json", "w", encoding="utf-8") as f: json.dump(sorted_result, f, ensure_ascii=False, indent=2) diff --git a/server.py b/server.py index f497f56..c41c543 100644 --- a/server.py +++ b/server.py @@ -1,21 +1,19 @@ -from flask import Flask, jsonify -from flask_apscheduler import APScheduler +from fastapi import FastAPI +from fastapi.responses import JSONResponse, HTMLResponse +from apscheduler.schedulers.asyncio import AsyncIOScheduler from threading import Lock import logging import os +import json +import random from friend_circle_lite.get_info import fetch_and_process_data, sort_articles_by_time from friend_circle_lite.get_conf import load_config -app = Flask(__name__) +app = FastAPI() # 配置APScheduler -class Config: - SCHEDULER_API_ENABLED = True - -app.config.from_object(Config()) -scheduler = APScheduler() -scheduler.init_app(app) +scheduler = AsyncIOScheduler() scheduler.start() # 配置日志记录 @@ -23,11 +21,15 @@ log_file = "grab.log" logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # 全局变量 -articles_data = [] +articles_data = { + "statistical_data": {}, + "article_data": [] +} +error_friends_info = [] data_lock = Lock() def fetch_articles(): - global articles_data + global articles_data, error_friends_info logging.info("开始抓取文章...") config = load_config("./conf.yaml") if config["spider_settings"]["enable"]: @@ -35,27 +37,65 @@ def fetch_articles(): article_count = config['spider_settings']['article_count'] logging.info(f"正在从 {json_url} 中获取,每个博客获取 {article_count} 篇文章") try: - result = fetch_and_process_data(json_url=json_url, count=article_count) + result, errors = fetch_and_process_data(json_url=json_url, count=article_count) sorted_result = sort_articles_by_time(result) with data_lock: articles_data = sorted_result + error_friends_info = errors logging.info("文章抓取成功") except Exception as e: logging.error(f"抓取文章时出错: {e}") # 每四个小时抓取一次文章 -scheduler.add_job(id='Fetch_Articles_Job', func=fetch_articles, trigger='interval', hours=4) +scheduler.add_job(fetch_articles, 'interval', hours=4) -@app.route('/all', methods=['GET']) -def get_all_articles(): +@app.get("/", response_class=HTMLResponse) +async def root(): + html_content = """ + + + + Friend Circle Lite + + +

欢迎使用 Friend Circle Lite

+

这是一个轻量版友链朋友圈,有两种部署方式,其中自部署使用 fastAPI,还有 github action 部署方式,可以很方便的从友链中获取文章并展示到前端。

+ + + + """ + return HTMLResponse(content=html_content) + +@app.get('/all') +async def get_all_articles(): with data_lock: - return jsonify(articles_data) + return JSONResponse(content=articles_data) + +@app.get('/errors') +async def get_error_friends(): + with data_lock: + return JSONResponse(content=error_friends_info) + +@app.get('/random') +async def get_random_article(): + with data_lock: + if articles_data["article_data"]: + random_article = random.choice(articles_data["article_data"]) + return JSONResponse(content=random_article) + else: + return JSONResponse(content={"error": "No articles available"}, status_code=404) if __name__ == '__main__': + import uvicorn + # 清空日志文件 if os.path.exists(log_file): with open(log_file, 'w'): pass fetch_articles() # 启动时立即抓取一次 - app.run(port=1223) + uvicorn.run(app, host='0.0.0.0', port=1223)