跳转至

以下内容基本上是 AI 生成的,我还没校对,可能质量不高

XindeX 习语录

xindex 是习近平语录搜索前端。后端 FastAPI 代理人民日报 API。

https://github.com/CNSeniorious000/xindex

实现

SvelteKit 前端,缓存搜索结果。代理重写 HTML。

后端 FastAPI

类似 cached-proxy,后端是一个独立的 FastAPI 服务,解决 CORS 的问题,并为搜索提供一层缓存。代码示例见 README.md

from fastapi import FastAPI, Response, Request, Query
from fastapi.responses import ORJSONResponse, StreamingResponse
from brotli_asgi import BrotliMiddleware
from httpx import AsyncClient
from bs4 import BeautifulSoup
from asyncache import cached
from cachetools import TTLCache

app = FastAPI(default_response_class=ORJSONResponse)
app.add_middleware(BrotliMiddleware, quality=3)

client = AsyncClient(http2=True, follow_redirects=True,
                     base_url="http://jhsjk.people.cn",
                     headers={"Accept-Encoding": "gzip", "User-Agent": ""})

搜索 API

@app.get("/search")
@cached(TTLCache(15, 60))  # 1 minute caching, max 15 items
async def search(fuzzy: bool = False, keywords="", sort_by: SortBy = ...,
                 num: int | None = Query(None, example=10, ge=1), reverse: bool = False):
    result = await find_all(fuzzy, keywords)
    if sort_by is not SortBy.no_sort:
        result.sort(key=itemgetter(sort_by.value), reverse=reverse)
    return result if num is None else result[:num]

图片代理

@app.get("/image/{article_id}")
async def fetch_image(article_id: int = Query(alias="articleId")):
    if url := await get_image(article_id):
        response = await client.get(url)
        return StreamingResponse(response.iter_bytes(8192),
                                 media_type=response.headers["Content-Type"])

缓存

TTLCache 存搜索(1分钟,15条目)和图片(10秒,100条目)。

前端架构

SvelteKit 前端,主要模块:

深入洞见

xindex 是一个 SvelteKit 前端 + FastAPI 后端的演示性采集/搜索前端:前端提供快速的 client-side 搜索体验,后端使用 FastAPI + asyncache/TTLCache + BrotliMiddleware 做缓存与压缩。

核心模块:

设计亮点:

  1. 双层缓存: 后端 TTLCache(1分钟)+ 前端 memoize-one
  2. SSR/CSR 兼容: fetchFromMirror.js 同时支持浏览器和 Node.js 环境
  3. 精细动画: 加载指示器、列表项入场、hover 效果均使用 Svelte transition
  4. 图标动态切换: 人民日报来源显示报纸图标,其他显示书本图标