Skip to content

Commit

Permalink
🦄 refactor: 调整接口结构
Browse files Browse the repository at this point in the history
  • Loading branch information
imsyy committed Dec 4, 2024
1 parent 0cce0d6 commit f38d264
Show file tree
Hide file tree
Showing 54 changed files with 348 additions and 362 deletions.
19 changes: 11 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
# 服务端口
PORT = 6688
PORT=6688

# 允许的域名
ALLOWED_DOMAIN = "*"
ALLOWED_DOMAIN="*"

# 允许的主域名,填写格式为 imsyy.top
## 若填写该项,将忽略 ALLOWED_DOMAIN
ALLOWED_HOST = ""
ALLOWED_HOST=""

# ROBOT
DISALLOW_ROBOT = true
DISALLOW_ROBOT=true

# 缓存时长( 秒 )
CACHE_TTL = 3600
CACHE_TTL=3600

# 请求超时( 毫秒 )
REQUEST_TIMEOUT = 6000
REQUEST_TIMEOUT=6000

# 是否输出日志
USE_LOG_FILE = true
USE_LOG_FILE=true

# RSS Mode
RSS_MODE = false
RSS_MODE=false

# Puppeteer
USE_PUPPETEER=false
17 changes: 16 additions & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
imsyy/dailyhot-api
ghcr.io/${{ github.repository }}
- name: Build and push
- name: Build and push regular image (no Puppeteer)
uses: docker/build-push-action@v5
with:
context: .
Expand All @@ -54,3 +54,18 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Build and push Puppeteer image (with Puppeteer)
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
platforms: |
linux/amd64
linux/arm64
push: true
tags: imsyy/dailyhot-api:web-latest
build-args: |
USE_PUPPETEER=true
labels: ${{ steps.meta.outputs.labels }}

28 changes: 23 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,27 @@ FROM node:20-alpine AS base
ENV NODE_ENV=docker

# 安装 Puppeteer 所需的依赖库
RUN apk add libc6-compat
# RUN apk add chromium nss freetype harfbuzz ca-certificates
RUN apk add --no-cache \
libc6-compat \
nss \
freetype \
harfbuzz \
ca-certificates

# 判断是否需要安装 Chromium
ARG USE_PUPPETEER=false
RUN if [ "$USE_PUPPETEER" = "true" ]; then \
apk add --no-cache chromium; \
fi

# 配置 Chromium
# ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
# ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# 清理缓存
RUN rm -rf /var/cache/apk/*

# 构建阶段
FROM base AS builder

RUN npm install -g pnpm
Expand All @@ -21,20 +35,24 @@ COPY public ./public

# add .env.example to .env
RUN [ ! -e ".env" ] && cp .env.example .env || true
RUN if [ "$USE_PUPPETEER" = "true" ]; then \
sed -i 's/^USE_PUPPETEER=false/USE_PUPPETEER=true/' .env; \
fi

RUN pnpm install
RUN pnpm build
RUN pnpm prune --production

# 运行阶段
FROM base AS runner
WORKDIR /app

# 创建用户和组
RUN addgroup --system --gid 114514 nodejs
RUN adduser --system --uid 114514 hono

# 创建日志目录
RUN mkdir -p /app/logs && chown -R hono:nodejs /app/logs
RUN ln -s /app/logs /logs

# 复制文件
COPY --from=builder --chown=hono:nodejs /app/node_modules /app/node_modules
Expand Down
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
| 虎扑 | 步行街热帖 | hupu | ![](https://img.shields.io/website.svg?label=hupu&url=https://api-hot.imsyy.top/hupu&cacheSeconds=7200) |
| 爱范儿 | 快讯 | ifanr | ![](https://img.shields.io/website.svg?label=ifanr&url=https://api-hot.imsyy.top/ifanr&cacheSeconds=7200) |
| 英雄联盟 | 更新公告 | lol | ![](https://img.shields.io/website.svg?label=lol&url=https://api-hot.imsyy.top/lol&cacheSeconds=7200) |
| 米游社 | 最新消息 | miyoushe | ![](https://img.shields.io/website.svg?label=miyoushe&url=https://api-hot.imsyy.top/miyoushe&cacheSeconds=7200) |
| 原神 | 最新消息 | genshin | ![](https://img.shields.io/website.svg?label=genshin&url=https://api-hot.imsyy.top/genshin&cacheSeconds=7200) |
| 崩坏3 | 最新动态 | honkai | ![](https://img.shields.io/website.svg?label=honkai&url=https://api-hot.imsyy.top/honkai&cacheSeconds=7200) |
| 崩坏:星穹铁道 | 最新动态 | starrail | ![](https://img.shields.io/website.svg?label=starrail&url=https://api-hot.imsyy.top/starrail&cacheSeconds=7200) |
Expand All @@ -83,6 +84,8 @@

本项目支持 `Node.js` 调用,可在安装完成后调用 `serveHotApi` 来开启服务器

> 该方式无法使用部分需要 Puppeteer 环境的接口
```bash
pnpm add dailyhot-api
```
Expand All @@ -100,6 +103,8 @@ serveHotApi(3000);

## ⚙️ 部署

由于部分接口无法通过接口调用等方式获取数据,故采用 `Puppeteer` 来实现,但由于使用后会造成 **内存占用过大或镜像过大**,可选择性开启,详情请参考下方说明。

具体使用说明可参考 [我的博客](https://blog.imsyy.top/posts/2024/0408),下方仅讲解基础操作:

### Docker 部署
Expand All @@ -111,8 +116,11 @@ serveHotApi(3000);
```bash
# 构建
docker build -t dailyhot-api .
# 构建 Puppeteer 版
docker build --build-arg USE_PUPPETEER=true -t dailyhot-api .

# 运行
docker run -p 6688:6688 -d dailyhot-api
docker run --restart always -p 6688:6688 -d dailyhot-api
# 或使用 Docker Compose
docker-compose up -d
```
Expand All @@ -122,8 +130,11 @@ docker-compose up -d
```bash
# 拉取
docker pull imsyy/dailyhot-api:latest
# 拉取 Puppeteer 版
docker pull imsyy/dailyhot-api:web-latest

# 运行
docker run -p 6688:6688 -d imsyy/dailyhot-api:latest
docker run --restart always -p 6688:6688 -d imsyy/dailyhot-api:latest
```

### 手动部署
Expand All @@ -148,7 +159,10 @@ npm install
#### 开发

```bash
# 标准运行
npm run dev
# 采用 Puppeteer 运行
npm run dev:web
```

成功启动后程序会在控制台输出可访问的地址
Expand All @@ -157,7 +171,11 @@ npm run dev

```bash
npm run build

# 标准运行
npm run start
# 采用 Puppeteer 运行
npm run start:web
```

成功启动后程序会在控制台输出可访问的地址
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
"format": "prettier --write .",
"lint": "eslint .",
"dev": "cross-env NODE_ENV=development tsx watch --no-cache src/index.ts",
"dev:web": "cross-env NODE_ENV=development USE_PUPPETEER=true tsx watch --no-cache src/index.ts",
"dev:cache": "cross-env NODE_ENV=development tsx watch src/index.ts",
"build": "tsc --project tsconfig.json",
"start": "cross-env NODE_ENV=development tsx dist/src/index.js"
"start": "cross-env NODE_ENV=development tsx dist/index.js",
"start:web": "cross-env NODE_ENV=development USE_PUPPETEER=true tsx dist/index.js"
},
"type": "module",
"dependencies": {
Expand All @@ -46,6 +48,7 @@
"hono": "^4.6.12",
"md5": "^2.3.0",
"node-cache": "^5.1.2",
"puppeteer": "^23.10.0",
"puppeteer-cluster": "^0.24.0",
"rss-parser": "^3.13.0",
"winston": "^3.17.0",
Expand Down
33 changes: 18 additions & 15 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type Config = {
ALLOWED_HOST: string;
USE_LOG_FILE: boolean;
RSS_MODE: boolean;
USE_PUPPETEER: boolean;
};

// 验证并提取环境变量
Expand Down Expand Up @@ -49,4 +50,5 @@ export const config: Config = {
ALLOWED_HOST: getEnvVariable("ALLOWED_HOST") || "imsyy.top",
USE_LOG_FILE: getBooleanEnvVariable("USE_LOG_FILE", true),
RSS_MODE: getBooleanEnvVariable("RSS_MODE", false),
USE_PUPPETEER: getBooleanEnvVariable("USE_PUPPETEER", false),
};
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { serve } from "@hono/node-server";
import { config } from "./config.js";
import packageJson from "../package.json";
import logger from "./utils/logger.js";
import app from "./app.js";

Expand All @@ -11,8 +10,8 @@ const serveHotApi: (port?: number) => void = (port: number = config.PORT) => {
fetch: app.fetch,
port,
});
logger.info(`📦 Version: ${packageJson.version}`);
logger.info(`🔥 DailyHot API 成功在端口 ${port} 上运行`);
logger.info(`💻 Puppeteer: ${config.USE_PUPPETEER}`);
logger.info(`🔗 Local: 👉 http://localhost:${port}`);
return apiServer;
} catch (error) {
Expand Down
11 changes: 4 additions & 7 deletions src/routes/36kr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const typeMap: Record<string, string> = {

export const handleRoute = async (c: ListContext, noCache: boolean) => {
const type = c.req.query("type") || "hot";
const { fromCache, data, updateTime } = await getList({ type }, noCache);
const listData = await getList({ type }, noCache);
const routeData: RouterData = {
name: "36kr",
title: "36氪",
Expand All @@ -24,10 +24,8 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
},
},
link: "https://m.36kr.com/hot-list-m",
total: data?.length || 0,
updateTime,
fromCache,
data,
total: listData.data?.length || 0,
...listData,
};
return routeData;
};
Expand Down Expand Up @@ -59,8 +57,7 @@ const getList = async (options: Options, noCache: boolean): Promise<RouterResTyp
const list =
result.data.data[(listType as Record<string, keyof typeof result.data.data>)[type || "hot"]];
return {
fromCache: result.fromCache,
updateTime: result.updateTime,
...result,
data: list.map((v: RouterType["36kr"]) => {
const item = v.templateMaterial;
return {
Expand Down
Loading

0 comments on commit f38d264

Please sign in to comment.