docs: Add documentation on how to add new sources (#122)
This commit is contained in:
+204
@@ -0,0 +1,204 @@
|
|||||||
|
# Contributing to NewsNow
|
||||||
|
|
||||||
|
Thank you for considering contributing to NewsNow! This document provides guidelines and instructions for contributing to the project.
|
||||||
|
|
||||||
|
## Adding a New Source
|
||||||
|
|
||||||
|
NewsNow is built to be easily extensible with new sources. Here's a step-by-step guide on how to add a new source:
|
||||||
|
|
||||||
|
### 1. Create a Feature Branch
|
||||||
|
|
||||||
|
Always create a feature branch for your changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, to add a Bilibili hot video source:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b bilibili-hot-video
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Register the Source in Configuration
|
||||||
|
|
||||||
|
Add your new source to the source configuration in `/shared/pre-sources.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
"bilibili": {
|
||||||
|
name: "哔哩哔哩",
|
||||||
|
color: "blue",
|
||||||
|
home: "https://www.bilibili.com",
|
||||||
|
sub: {
|
||||||
|
"hot-search": {
|
||||||
|
title: "热搜",
|
||||||
|
column: "china",
|
||||||
|
type: "hottest"
|
||||||
|
},
|
||||||
|
"hot-video": { // Add your new sub-source here
|
||||||
|
title: "热门视频",
|
||||||
|
column: "china",
|
||||||
|
type: "hottest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
For a completely new source, add a new top-level entry:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
"newsource": {
|
||||||
|
name: "New Source",
|
||||||
|
color: "blue",
|
||||||
|
home: "https://www.example.com",
|
||||||
|
column: "tech", // Pick an appropriate column
|
||||||
|
type: "hottest" // Or "realtime" if it's a news feed
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Implement the Source Fetcher
|
||||||
|
|
||||||
|
Create or modify a file in the `/server/sources/` directory. If your source is related to an existing one (like adding a new Bilibili sub-source), modify the existing file:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// In /server/sources/bilibili.ts
|
||||||
|
|
||||||
|
// Define interface for API response
|
||||||
|
interface HotVideoRes {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
ttl: number;
|
||||||
|
data: {
|
||||||
|
list: {
|
||||||
|
aid: number;
|
||||||
|
// ... other fields
|
||||||
|
bvid: string;
|
||||||
|
title: string;
|
||||||
|
pubdate: number;
|
||||||
|
desc: string;
|
||||||
|
pic: string;
|
||||||
|
owner: {
|
||||||
|
mid: number;
|
||||||
|
name: string;
|
||||||
|
face: string;
|
||||||
|
};
|
||||||
|
stat: {
|
||||||
|
view: number;
|
||||||
|
like: number;
|
||||||
|
reply: number;
|
||||||
|
// ... other stats
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define source getter function
|
||||||
|
const hotVideo = defineSource(async () => {
|
||||||
|
const url = "https://api.bilibili.com/x/web-interface/popular";
|
||||||
|
const res: HotVideoRes = await myFetch(url);
|
||||||
|
|
||||||
|
return res.data.list.map((video) => ({
|
||||||
|
id: video.bvid,
|
||||||
|
title: video.title,
|
||||||
|
url: `https://www.bilibili.com/video/${video.bvid}`,
|
||||||
|
pubDate: video.pubdate * 1000,
|
||||||
|
extra: {
|
||||||
|
info: `${video.owner.name} · ${formatNumber(video.stat.view)}观看 · ${formatNumber(video.stat.like)}点赞`,
|
||||||
|
hover: video.desc,
|
||||||
|
icon: proxyPicture(video.pic),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Helper function for formatting numbers
|
||||||
|
function formatNumber(num: number): string {
|
||||||
|
if (num >= 10000) {
|
||||||
|
return `${Math.floor(num / 10000)}w+`;
|
||||||
|
}
|
||||||
|
return num.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export the source
|
||||||
|
export default defineSource({
|
||||||
|
bilibili: hotSearch,
|
||||||
|
"bilibili-hot-search": hotSearch,
|
||||||
|
"bilibili-hot-video": hotVideo, // Add your new source here
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
For completely new sources, create a new file in `/server/sources/` named after your source (e.g., `newsource.ts`).
|
||||||
|
|
||||||
|
### 4. Regenerate Source Files
|
||||||
|
|
||||||
|
After adding or modifying source files, run the following command to regenerate the necessary files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run presource
|
||||||
|
```
|
||||||
|
|
||||||
|
This will update the `sources.json` file and any other necessary configuration.
|
||||||
|
|
||||||
|
### 5. Test Your Changes
|
||||||
|
|
||||||
|
Start the development server to test your changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Access the application in your browser and ensure that your new source is appearing and working correctly.
|
||||||
|
|
||||||
|
### 6. Commit Your Changes
|
||||||
|
|
||||||
|
Once everything is working, commit your changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "Add new source: source-name"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Create a Pull Request
|
||||||
|
|
||||||
|
Push your changes to your fork and create a pull request against the main repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git push origin feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
## Source Structure
|
||||||
|
|
||||||
|
### NewsItem Structure
|
||||||
|
|
||||||
|
Each source should return an array of objects that conform to the `NewsItem` interface:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface NewsItem {
|
||||||
|
id: string | number; // Unique identifier for the item
|
||||||
|
title: string; // Title of the news item
|
||||||
|
url: string; // URL to the full content
|
||||||
|
mobileUrl?: string; // Optional mobile-specific URL
|
||||||
|
pubDate?: number | string; // Publication date
|
||||||
|
extra?: {
|
||||||
|
hover?: string; // Text to display on hover
|
||||||
|
date?: number | string; // Formatted date
|
||||||
|
info?: false | string; // Additional information
|
||||||
|
diff?: number; // Time difference
|
||||||
|
icon?:
|
||||||
|
| false
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
// Icon for the item
|
||||||
|
url: string;
|
||||||
|
scale: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
Please follow the existing code style in the project. The project uses TypeScript and follows modern ES6+ conventions.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing to this project, you agree that your contributions will be licensed under the project's license.
|
||||||
@@ -9,9 +9,10 @@ English | [简体中文](README.zh-CN.md) | [日本語](README.ja-JP.md)
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> This is a demo version currently supporting Chinese only. A full-featured version with better customization and English content support will be released later.
|
> This is a demo version currently supporting Chinese only. A full-featured version with better customization and English content support will be released later.
|
||||||
|
|
||||||
***Elegant reading of real-time and hottest news***
|
**_Elegant reading of real-time and hottest news_**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Clean and elegant UI design for optimal reading experience
|
- Clean and elegant UI design for optimal reading experience
|
||||||
- Real-time updates on trending news
|
- Real-time updates on trending news
|
||||||
- GitHub OAuth login with data synchronization
|
- GitHub OAuth login with data synchronization
|
||||||
@@ -21,21 +22,26 @@ English | [简体中文](README.zh-CN.md) | [日本語](README.ja-JP.md)
|
|||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
### Basic Deployment
|
### Basic Deployment
|
||||||
|
|
||||||
For deployments without login and caching:
|
For deployments without login and caching:
|
||||||
|
|
||||||
1. Fork this repository
|
1. Fork this repository
|
||||||
2. Import to platforms like Cloudflare Page or Vercel
|
2. Import to platforms like Cloudflare Page or Vercel
|
||||||
|
|
||||||
### Cloudflare Page Configuration
|
### Cloudflare Page Configuration
|
||||||
|
|
||||||
- Build command: `pnpm run build`
|
- Build command: `pnpm run build`
|
||||||
- Output directory: `dist/output/public`
|
- Output directory: `dist/output/public`
|
||||||
|
|
||||||
### GitHub OAuth Setup
|
### GitHub OAuth Setup
|
||||||
|
|
||||||
1. [Create a GitHub App](https://github.com/settings/applications/new)
|
1. [Create a GitHub App](https://github.com/settings/applications/new)
|
||||||
2. No special permissions required
|
2. No special permissions required
|
||||||
3. Set callback URL to: `https://your-domain.com/api/oauth/github` (replace `your-domain` with your actual domain)
|
3. Set callback URL to: `https://your-domain.com/api/oauth/github` (replace `your-domain` with your actual domain)
|
||||||
4. Obtain Client ID and Client Secret
|
4. Obtain Client ID and Client Secret
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
Refer to `example.env.server`. For local development, rename it to `.env.server` and configure:
|
Refer to `example.env.server`. For local development, rename it to `.env.server` and configure:
|
||||||
|
|
||||||
```env
|
```env
|
||||||
@@ -52,14 +58,17 @@ ENABLE_CACHE=true
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Database Support
|
### Database Support
|
||||||
|
|
||||||
Supported database connectors: https://db0.unjs.io/connectors
|
Supported database connectors: https://db0.unjs.io/connectors
|
||||||
**Cloudflare D1 Database** is recommended.
|
**Cloudflare D1 Database** is recommended.
|
||||||
|
|
||||||
1. Create D1 database in Cloudflare Worker dashboard
|
1. Create D1 database in Cloudflare Worker dashboard
|
||||||
2. Configure database_id and database_name in wrangler.toml
|
2. Configure database_id and database_name in wrangler.toml
|
||||||
3. If wrangler.toml doesn't exist, rename example.wrangler.toml and modify configurations
|
3. If wrangler.toml doesn't exist, rename example.wrangler.toml and modify configurations
|
||||||
4. Changes will take effect on next deployment
|
4. Changes will take effect on next deployment
|
||||||
|
|
||||||
### Docker Deployment
|
### Docker Deployment
|
||||||
|
|
||||||
In project root directory:
|
In project root directory:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -69,6 +78,7 @@ docker compose up
|
|||||||
You can also set Environment Variables in `docker-compose.yml`.
|
You can also set Environment Variables in `docker-compose.yml`.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
> [!Note]
|
> [!Note]
|
||||||
> Requires Node.js >= 20
|
> Requires Node.js >= 20
|
||||||
|
|
||||||
@@ -79,19 +89,26 @@ pnpm dev
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Adding Data Sources
|
### Adding Data Sources
|
||||||
Refer to `shared/sources` and `server/source`s directories. The project provides complete type definitions and a clean architecture.
|
|
||||||
|
Refer to `shared/sources` and `server/sources` directories. The project provides complete type definitions and a clean architecture.
|
||||||
|
|
||||||
|
For detailed instructions on how to add new sources, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- Add **multi-language support** (English, Chinese, more to come).
|
- Add **multi-language support** (English, Chinese, more to come).
|
||||||
- Improve **personalization options** (category-based news, saved preferences).
|
- Improve **personalization options** (category-based news, saved preferences).
|
||||||
- Expand **data sources** to cover global news in multiple languages.
|
- Expand **data sources** to cover global news in multiple languages.
|
||||||
|
|
||||||
***release when ready***
|
**_release when ready_**
|
||||||

|

|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are welcome! Feel free to submit pull requests or create issues for feature requests and bug reports.
|
Contributions are welcome! Feel free to submit pull requests or create issues for feature requests and bug reports.
|
||||||
|
|
||||||
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines on how to contribute, especially for adding new data sources.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](./LICENSE) © ourongxing
|
[MIT](./LICENSE) © ourongxing
|
||||||
|
|||||||
Reference in New Issue
Block a user