rss-agent-viewer 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/bin/rss-viewer +77 -0
- package/dist/cli/commands.d.ts +18 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +384 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/core/cache.d.ts +23 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +53 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/discovery.d.ts +3 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +171 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/filter.d.ts +11 -0
- package/dist/core/filter.d.ts.map +1 -0
- package/dist/core/filter.js +36 -0
- package/dist/core/filter.js.map +1 -0
- package/dist/core/opml.d.ts +17 -0
- package/dist/core/opml.d.ts.map +1 -0
- package/dist/core/opml.js +73 -0
- package/dist/core/opml.js.map +1 -0
- package/dist/core/parser.d.ts +17 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +31 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/types.d.ts +42 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/config.d.ts +11 -0
- package/dist/storage/config.d.ts.map +1 -0
- package/dist/storage/config.js +58 -0
- package/dist/storage/config.js.map +1 -0
- package/dist/storage/database.d.ts +58 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +236 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/utils/formatter.d.ts +10 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +40 -0
- package/dist/utils/formatter.js.map +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# RSS Agent Viewer
|
|
2
|
+
|
|
3
|
+
CLI RSS/Atom feed viewer with automatic feed discovery via `rss-agent-discovery`.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g rss-agent-viewer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run without installation:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx rss-viewer
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Initialize configuration
|
|
21
|
+
rss-viewer init
|
|
22
|
+
|
|
23
|
+
# Add a feed
|
|
24
|
+
rss-viewer add https://vercel.com/atom
|
|
25
|
+
|
|
26
|
+
# List all feeds
|
|
27
|
+
rss-viewer feeds
|
|
28
|
+
|
|
29
|
+
# Read articles
|
|
30
|
+
rss-viewer read
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
- `init` - Initialize configuration and database
|
|
36
|
+
- `add <url>` - Add a feed to the database
|
|
37
|
+
- `discover <url>` - Discover feeds from a URL
|
|
38
|
+
- `feeds` - List all subscribed feeds
|
|
39
|
+
- `remove <url>` - Remove a feed by URL
|
|
40
|
+
- `read [url]` - Read articles from a feed or all feeds
|
|
41
|
+
- `search <query>` - Search across all feeds
|
|
42
|
+
- `import <file>` - Import feeds from OPML file
|
|
43
|
+
- `export` - Export feeds to OPML or JSON
|
|
44
|
+
- `cache <action>` - Manage cache (stats, clear, refresh)
|
|
45
|
+
|
|
46
|
+
## Development
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Install dependencies
|
|
50
|
+
npm install
|
|
51
|
+
|
|
52
|
+
# Build
|
|
53
|
+
npm run build
|
|
54
|
+
|
|
55
|
+
# Run tests
|
|
56
|
+
npm test
|
|
57
|
+
|
|
58
|
+
# Development mode
|
|
59
|
+
npm run dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT
|
package/bin/rss-viewer
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { handleInit, handleAdd, handleDiscover, handleFeeds, handleRemove, handleRead, handleSearch, handleImport, handleExport, handleCache } from '../dist/cli/commands.js';
|
|
4
|
+
|
|
5
|
+
const program = new Command();
|
|
6
|
+
|
|
7
|
+
program
|
|
8
|
+
.name('rss-viewer')
|
|
9
|
+
.description('CLI RSS/Atom feed viewer with automatic feed discovery')
|
|
10
|
+
.version('0.1.0');
|
|
11
|
+
|
|
12
|
+
program
|
|
13
|
+
.command('init')
|
|
14
|
+
.description('Initialize configuration and database')
|
|
15
|
+
.action(handleInit);
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.command('add <url>')
|
|
19
|
+
.description('Add a feed to database')
|
|
20
|
+
.option('--discover', 'Auto-discover feeds from URL')
|
|
21
|
+
.option('--category <name>', 'Feed category')
|
|
22
|
+
.action(handleAdd);
|
|
23
|
+
|
|
24
|
+
program
|
|
25
|
+
.command('discover <url>')
|
|
26
|
+
.description('Discover feeds from a URL')
|
|
27
|
+
.option('--timeout <ms>', 'Discovery timeout in milliseconds', '10000')
|
|
28
|
+
.option('--skip-blogs', 'Skip blog scanning')
|
|
29
|
+
.option('--max-blogs <n>', 'Maximum blog paths to scan', '5')
|
|
30
|
+
.action(handleDiscover);
|
|
31
|
+
|
|
32
|
+
program
|
|
33
|
+
.command('feeds')
|
|
34
|
+
.description('List all subscribed feeds')
|
|
35
|
+
.action(handleFeeds);
|
|
36
|
+
|
|
37
|
+
program
|
|
38
|
+
.command('remove <url>')
|
|
39
|
+
.description('Remove a feed by URL')
|
|
40
|
+
.action(handleRemove);
|
|
41
|
+
|
|
42
|
+
program
|
|
43
|
+
.command('read [url]')
|
|
44
|
+
.description('Read articles from a feed or all feeds')
|
|
45
|
+
.option('--all', 'Read from all feeds')
|
|
46
|
+
.option('--limit <n>', 'Maximum number of articles', '20')
|
|
47
|
+
.option('--since <date>', 'Show articles newer than date')
|
|
48
|
+
.option('--author <name>', 'Filter by author')
|
|
49
|
+
.option('--tag <tag>', 'Filter by tag/category')
|
|
50
|
+
.option('--reverse', 'Show oldest articles first')
|
|
51
|
+
.action(handleRead);
|
|
52
|
+
|
|
53
|
+
program
|
|
54
|
+
.command('search <query>')
|
|
55
|
+
.description('Search across all feeds')
|
|
56
|
+
.option('--limit <n>', 'Maximum number of articles', '20')
|
|
57
|
+
.option('--since <date>', 'Show articles newer than date')
|
|
58
|
+
.option('--tag <tag>', 'Filter by tag/category')
|
|
59
|
+
.action(handleSearch);
|
|
60
|
+
|
|
61
|
+
program
|
|
62
|
+
.command('import <file>')
|
|
63
|
+
.description('Import feeds from OPML file')
|
|
64
|
+
.action(handleImport);
|
|
65
|
+
|
|
66
|
+
program
|
|
67
|
+
.command('export')
|
|
68
|
+
.description('Export feeds to OPML or JSON')
|
|
69
|
+
.option('--format <format>', 'Output format (opml|json)', 'opml')
|
|
70
|
+
.action(handleExport);
|
|
71
|
+
|
|
72
|
+
program
|
|
73
|
+
.command('cache <action>')
|
|
74
|
+
.description('Manage cache (stats, clear, refresh)')
|
|
75
|
+
.action(handleCache);
|
|
76
|
+
|
|
77
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare function handleInit(): Promise<void>;
|
|
2
|
+
export declare function handleAdd(url: string, options: {
|
|
3
|
+
discover?: boolean;
|
|
4
|
+
category?: string;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
export declare function handleDiscover(url: string, options: {
|
|
7
|
+
timeout?: number;
|
|
8
|
+
skipBlogs?: boolean;
|
|
9
|
+
maxBlogs?: number;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export declare function handleFeeds(): Promise<void>;
|
|
12
|
+
export declare function handleRemove(url: string): Promise<void>;
|
|
13
|
+
export declare function handleRead(url: string | undefined, options: any): Promise<void>;
|
|
14
|
+
export declare function handleSearch(query: string, options: any): Promise<void>;
|
|
15
|
+
export declare function handleImport(file: string): Promise<void>;
|
|
16
|
+
export declare function handleExport(format: string): Promise<void>;
|
|
17
|
+
export declare function handleCache(action: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAqCA,wBAAsB,UAAU,kBAgB/B;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,iBAiE9F;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,iBA2CtH;AAED,wBAAsB,WAAW,kBAchC;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,iBAgB7C;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,GAAG,iBA8GrE;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,iBAkB7D;AAoBD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,iBAkC9C;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,iBAoBhD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,iBA6B/C"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { FeedDatabase } from '../storage/database.js';
|
|
5
|
+
import { DiscoveryCache } from '../core/cache.js';
|
|
6
|
+
import { parseFeed } from '../core/parser.js';
|
|
7
|
+
import { generateOPML, importOPMLFile } from '../core/opml.js';
|
|
8
|
+
import { initConfig, loadConfig } from '../storage/config.js';
|
|
9
|
+
import { formatFeedsTable } from '../utils/formatter.js';
|
|
10
|
+
let db = null;
|
|
11
|
+
let discoveryCache = null;
|
|
12
|
+
let config = null;
|
|
13
|
+
function getConfig() {
|
|
14
|
+
if (!config) {
|
|
15
|
+
config = loadConfig();
|
|
16
|
+
}
|
|
17
|
+
return config;
|
|
18
|
+
}
|
|
19
|
+
function getDatabase() {
|
|
20
|
+
if (!db) {
|
|
21
|
+
db = new FeedDatabase(getConfig().databasePath);
|
|
22
|
+
}
|
|
23
|
+
return db;
|
|
24
|
+
}
|
|
25
|
+
function getDiscoveryCache() {
|
|
26
|
+
if (!discoveryCache) {
|
|
27
|
+
const cacheTTLSeconds = Math.max(1, Math.round(getConfig().cacheTTL / 1000));
|
|
28
|
+
discoveryCache = new DiscoveryCache(getDatabase(), cacheTTLSeconds);
|
|
29
|
+
}
|
|
30
|
+
return discoveryCache;
|
|
31
|
+
}
|
|
32
|
+
export async function handleInit() {
|
|
33
|
+
const initialized = initConfig();
|
|
34
|
+
const configDir = join(initialized.configPath, '..');
|
|
35
|
+
if (!existsSync(configDir)) {
|
|
36
|
+
console.log(chalk.dim(`Creating config directory: ${configDir}`));
|
|
37
|
+
}
|
|
38
|
+
const testDb = new FeedDatabase(initialized.databasePath);
|
|
39
|
+
testDb.close();
|
|
40
|
+
console.log(`${chalk.green('✓')} Database created at: ${initialized.databasePath}`);
|
|
41
|
+
console.log(`${chalk.green('✓')} Config path: ${initialized.configPath}`);
|
|
42
|
+
console.log('\nYou can now add feeds with:');
|
|
43
|
+
console.log(' rss-viewer add <url>');
|
|
44
|
+
console.log(' rss-viewer discover <url>');
|
|
45
|
+
}
|
|
46
|
+
export async function handleAdd(url, options) {
|
|
47
|
+
const database = getDatabase();
|
|
48
|
+
const cache = getDiscoveryCache();
|
|
49
|
+
const settings = getConfig();
|
|
50
|
+
let feedUrl = url;
|
|
51
|
+
let feedTitle = url;
|
|
52
|
+
let feedType = 'rss';
|
|
53
|
+
if (options.discover) {
|
|
54
|
+
console.log(chalk.dim(`Auto-discovering feeds from: ${url}`));
|
|
55
|
+
const cached = cache.get(url);
|
|
56
|
+
let discoveredFeeds = [];
|
|
57
|
+
if (cached && cached.results[0]?.feeds?.length > 0) {
|
|
58
|
+
console.log(`${chalk.green('✓')} Using cached discovery results`);
|
|
59
|
+
discoveredFeeds = cached.results[0].feeds;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const { discoverFeeds } = await import('../core/discovery.js');
|
|
63
|
+
const result = discoverFeeds(url, {
|
|
64
|
+
timeout: settings.discoveryTimeout,
|
|
65
|
+
skipBlogs: false,
|
|
66
|
+
maxBlogs: settings.maxBlogs
|
|
67
|
+
});
|
|
68
|
+
if (result.success && result.results[0]?.feeds?.length > 0) {
|
|
69
|
+
discoveredFeeds = result.results[0].feeds;
|
|
70
|
+
cache.set(url, result);
|
|
71
|
+
console.log(`${chalk.green('✓')} Found ${discoveredFeeds.length} feed(s) from discovery`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(`${chalk.yellow('○')} No feeds found, adding as manual feed`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (discoveredFeeds.length > 0) {
|
|
78
|
+
feedUrl = discoveredFeeds[0].url;
|
|
79
|
+
feedTitle = discoveredFeeds[0].title || url;
|
|
80
|
+
feedType = discoveredFeeds[0].type === 'unknown' ? 'rss' : discoveredFeeds[0].type;
|
|
81
|
+
console.log(chalk.dim(` Using: ${feedUrl}`));
|
|
82
|
+
console.log(chalk.dim(` Title: ${feedTitle}`));
|
|
83
|
+
console.log(chalk.dim(` Type: ${feedType}`));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const category = options.category || 'General';
|
|
87
|
+
try {
|
|
88
|
+
const feedId = database.addFeed({
|
|
89
|
+
url: feedUrl,
|
|
90
|
+
title: feedTitle,
|
|
91
|
+
link: feedUrl,
|
|
92
|
+
type: feedType,
|
|
93
|
+
category
|
|
94
|
+
});
|
|
95
|
+
console.log(`${chalk.green('✓')} Added feed: ${feedUrl}`);
|
|
96
|
+
console.log(chalk.dim(` Category: ${category}`));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error(`${chalk.red('✗')} Failed to add feed: ${error instanceof Error ? error.message : String(error)}`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export async function handleDiscover(url, options) {
|
|
104
|
+
console.log(chalk.dim(`Discovering feeds from: ${url}`));
|
|
105
|
+
const cache = getDiscoveryCache();
|
|
106
|
+
const settings = getConfig();
|
|
107
|
+
const cached = cache.get(url);
|
|
108
|
+
if (cached) {
|
|
109
|
+
console.log(`${chalk.green('✓')} Using cached discovery results`);
|
|
110
|
+
if (cached.success && cached.results[0].feeds.length > 0) {
|
|
111
|
+
cached.results[0].feeds.forEach((feed) => {
|
|
112
|
+
console.log(chalk.dim(` Found: ${feed.url} (${feed.title}, ${feed.type})`));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const { discoverFeeds } = await import('../core/discovery.js');
|
|
118
|
+
const result = discoverFeeds(url, {
|
|
119
|
+
timeout: options.timeout || settings.discoveryTimeout,
|
|
120
|
+
skipBlogs: options.skipBlogs,
|
|
121
|
+
maxBlogs: options.maxBlogs || settings.maxBlogs,
|
|
122
|
+
verbose: false
|
|
123
|
+
});
|
|
124
|
+
if (result.success) {
|
|
125
|
+
const feeds = result.results[0]?.feeds || [];
|
|
126
|
+
if (feeds.length > 0) {
|
|
127
|
+
console.log(`${chalk.green('✓')} Found ${feeds.length} feed(s):`);
|
|
128
|
+
feeds.forEach((feed) => {
|
|
129
|
+
console.log(chalk.dim(` ${feed.url} (${feed.title}, ${feed.type})`));
|
|
130
|
+
});
|
|
131
|
+
cache.set(url, result);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.log(`${chalk.yellow('○')} No feeds found`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const error = result.results[0]?.error || 'Unknown error';
|
|
139
|
+
console.log(`${chalk.red('✗')} Discovery failed: ${error}`);
|
|
140
|
+
process.exit(2);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export async function handleFeeds() {
|
|
144
|
+
const database = getDatabase();
|
|
145
|
+
const feeds = database.getAllFeeds();
|
|
146
|
+
if (feeds.length === 0) {
|
|
147
|
+
console.log(chalk.yellow('No feeds found. Add a feed with:'));
|
|
148
|
+
console.log(' rss-viewer add <url>');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
console.log(`\n${chalk.bold('Subscribed Feeds')}`);
|
|
152
|
+
console.log(formatFeedsTable(feeds));
|
|
153
|
+
console.log(chalk.dim(`\nTotal: ${feeds.length} feeds`));
|
|
154
|
+
}
|
|
155
|
+
export async function handleRemove(url) {
|
|
156
|
+
const database = getDatabase();
|
|
157
|
+
const feed = database.getFeedByUrl(url);
|
|
158
|
+
if (!feed) {
|
|
159
|
+
console.log(`${chalk.red('✗')} Feed not found: ${url}`);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
const removed = database.removeFeed(url);
|
|
163
|
+
if (removed) {
|
|
164
|
+
console.log(`${chalk.green('✓')} Removed feed: ${feed.title}`);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.log(`${chalk.red('✗')} Failed to remove feed`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export async function handleRead(url, options) {
|
|
172
|
+
const database = getDatabase();
|
|
173
|
+
if (url) {
|
|
174
|
+
const feed = database.getFeedByUrl(url);
|
|
175
|
+
if (!feed) {
|
|
176
|
+
console.log(`${chalk.red('✗')} Feed not found: ${url}`);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
// Fetch and store articles from the feed
|
|
180
|
+
console.log(chalk.dim(`Fetching: ${feed.url}`));
|
|
181
|
+
try {
|
|
182
|
+
const parsedFeed = await parseFeed(feed.url);
|
|
183
|
+
// Update feed title if it changed
|
|
184
|
+
if (parsedFeed.title !== feed.title) {
|
|
185
|
+
database.addFeed({
|
|
186
|
+
url: feed.url,
|
|
187
|
+
title: parsedFeed.title,
|
|
188
|
+
link: parsedFeed.link,
|
|
189
|
+
type: feed.type,
|
|
190
|
+
category: feed.category
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// Store articles
|
|
194
|
+
let fetched = 0;
|
|
195
|
+
for (const item of parsedFeed.items) {
|
|
196
|
+
database.addArticle({
|
|
197
|
+
feedId: feed.id,
|
|
198
|
+
title: item.title,
|
|
199
|
+
link: item.link,
|
|
200
|
+
content: item.content,
|
|
201
|
+
summary: item.contentSnippet,
|
|
202
|
+
author: item.author,
|
|
203
|
+
publishedAt: item.pubDate ? item.pubDate.toISOString() : new Date().toISOString(),
|
|
204
|
+
readAt: null
|
|
205
|
+
});
|
|
206
|
+
fetched++;
|
|
207
|
+
}
|
|
208
|
+
console.log(`${chalk.green('✓')} Fetched ${fetched} articles`);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
console.log(`${chalk.yellow('⚠')} Failed to fetch feed: ${error instanceof Error ? error.message : String(error)}`);
|
|
212
|
+
}
|
|
213
|
+
const limit = options.limit ? parseInt(options.limit) : 20;
|
|
214
|
+
const articles = database.getArticlesByFeedId(feed.id, limit);
|
|
215
|
+
console.log(`\nReading from: ${feed.title}\n`);
|
|
216
|
+
displayArticles(articles);
|
|
217
|
+
if (db) {
|
|
218
|
+
db.close();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// Fetch from all feeds if --all flag is set
|
|
223
|
+
if (options.all) {
|
|
224
|
+
const feeds = database.getAllFeeds();
|
|
225
|
+
console.log(chalk.dim(`Fetching from ${feeds.length} feed(s)...`));
|
|
226
|
+
for (const feed of feeds) {
|
|
227
|
+
try {
|
|
228
|
+
const parsedFeed = await parseFeed(feed.url);
|
|
229
|
+
// Update feed title if it changed
|
|
230
|
+
if (parsedFeed.title !== feed.title) {
|
|
231
|
+
database.addFeed({
|
|
232
|
+
url: feed.url,
|
|
233
|
+
title: parsedFeed.title,
|
|
234
|
+
link: parsedFeed.link,
|
|
235
|
+
type: feed.type,
|
|
236
|
+
category: feed.category
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// Store articles
|
|
240
|
+
for (const item of parsedFeed.items) {
|
|
241
|
+
database.addArticle({
|
|
242
|
+
feedId: feed.id,
|
|
243
|
+
title: item.title,
|
|
244
|
+
link: item.link,
|
|
245
|
+
content: item.content,
|
|
246
|
+
summary: item.contentSnippet,
|
|
247
|
+
author: item.author,
|
|
248
|
+
publishedAt: item.pubDate ? item.pubDate.toISOString() : new Date().toISOString(),
|
|
249
|
+
readAt: null
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
console.log(chalk.dim(` ✓ ${feed.title}`));
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
console.log(chalk.dim(` ✗ ${feed.title}: ${error instanceof Error ? error.message : String(error)}`));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const filters = {};
|
|
260
|
+
if (options.limit)
|
|
261
|
+
filters.limit = parseInt(options.limit);
|
|
262
|
+
if (options.since)
|
|
263
|
+
filters.since = new Date(options.since);
|
|
264
|
+
if (options.author)
|
|
265
|
+
filters.author = options.author;
|
|
266
|
+
if (options.tag)
|
|
267
|
+
filters.category = options.tag;
|
|
268
|
+
const articles = database.filterArticles(filters);
|
|
269
|
+
console.log('\nReading from all feeds\n');
|
|
270
|
+
displayArticles(articles);
|
|
271
|
+
if (db) {
|
|
272
|
+
db.close();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
export async function handleSearch(query, options) {
|
|
277
|
+
const database = getDatabase();
|
|
278
|
+
const filters = {};
|
|
279
|
+
if (options.limit)
|
|
280
|
+
filters.limit = parseInt(options.limit);
|
|
281
|
+
if (options.since)
|
|
282
|
+
filters.since = new Date(options.since);
|
|
283
|
+
if (options.author)
|
|
284
|
+
filters.author = options.author;
|
|
285
|
+
if (options.tag)
|
|
286
|
+
filters.category = options.tag;
|
|
287
|
+
const articles = database.filterArticles(filters);
|
|
288
|
+
if (articles.length === 0) {
|
|
289
|
+
console.log(chalk.yellow(`No articles found for: "${query}"`));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
console.log(`\n${chalk.bold(`Search results for: "${query}"`)}\n`);
|
|
293
|
+
displayArticles(articles);
|
|
294
|
+
}
|
|
295
|
+
function displayArticles(articles) {
|
|
296
|
+
if (articles.length === 0) {
|
|
297
|
+
console.log(chalk.yellow('No articles found.'));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
articles.forEach((article, index) => {
|
|
301
|
+
const published = article.publishedAt ? new Date(article.publishedAt).toLocaleDateString() : 'Unknown';
|
|
302
|
+
const readStatus = article.readAt ? chalk.green('✓') : chalk.dim('○');
|
|
303
|
+
console.log(`\n${chalk.bold(`${index + 1}. ${article.title}`)}`);
|
|
304
|
+
console.log(chalk.dim(` ${article.link}`));
|
|
305
|
+
console.log(chalk.dim(` Published: ${published} ${readStatus}`));
|
|
306
|
+
});
|
|
307
|
+
console.log(chalk.dim(`\nTotal: ${articles.length} articles`));
|
|
308
|
+
}
|
|
309
|
+
export async function handleImport(file) {
|
|
310
|
+
console.log(chalk.dim(`Importing from: ${file}`));
|
|
311
|
+
const database = getDatabase();
|
|
312
|
+
try {
|
|
313
|
+
const opml = importOPMLFile(file);
|
|
314
|
+
if (opml.feeds.length === 0) {
|
|
315
|
+
console.log(chalk.yellow('No feeds found in OPML file'));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
let imported = 0;
|
|
319
|
+
for (const feed of opml.feeds) {
|
|
320
|
+
database.addFeed({
|
|
321
|
+
url: feed.url,
|
|
322
|
+
title: feed.title,
|
|
323
|
+
link: feed.url,
|
|
324
|
+
type: 'rss',
|
|
325
|
+
category: feed.category || 'General'
|
|
326
|
+
});
|
|
327
|
+
imported++;
|
|
328
|
+
}
|
|
329
|
+
console.log(`${chalk.green('✓')} Imported ${imported} feed(s) from OPML`);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
console.error(`${chalk.red('✗')} Failed to import: ${error instanceof Error ? error.message : String(error)}`);
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
if (db) {
|
|
336
|
+
db.close();
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
export async function handleExport(format) {
|
|
340
|
+
const database = getDatabase();
|
|
341
|
+
const feeds = database.getAllFeeds();
|
|
342
|
+
if (format === 'json') {
|
|
343
|
+
console.log(JSON.stringify(feeds, null, 2));
|
|
344
|
+
}
|
|
345
|
+
else if (format === 'opml') {
|
|
346
|
+
const feedsForOPML = feeds.map(feed => ({
|
|
347
|
+
url: feed.url,
|
|
348
|
+
title: feed.title,
|
|
349
|
+
category: feed.category
|
|
350
|
+
}));
|
|
351
|
+
console.log(generateOPML(feedsForOPML));
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
console.log(chalk.red(`Unknown format: ${format}`));
|
|
355
|
+
console.log(chalk.dim('Available formats: json, opml'));
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
export async function handleCache(action) {
|
|
360
|
+
const database = getDatabase();
|
|
361
|
+
switch (action) {
|
|
362
|
+
case 'stats':
|
|
363
|
+
const stats = database.getCacheStats();
|
|
364
|
+
console.log(chalk.bold('Cache Statistics:'));
|
|
365
|
+
console.log(chalk.dim(` Entries: ${stats.count}`));
|
|
366
|
+
console.log(chalk.dim(` Size: ${(stats.size / 1024).toFixed(2)} KB`));
|
|
367
|
+
break;
|
|
368
|
+
case 'clear':
|
|
369
|
+
database.clearCache();
|
|
370
|
+
console.log(`${chalk.green('✓')} Cache cleared`);
|
|
371
|
+
break;
|
|
372
|
+
case 'refresh':
|
|
373
|
+
console.log(chalk.yellow('Cache refresh not yet implemented'));
|
|
374
|
+
break;
|
|
375
|
+
default:
|
|
376
|
+
console.log(chalk.red(`Unknown cache action: ${action}`));
|
|
377
|
+
console.log(chalk.dim('Available actions: stats, clear, refresh'));
|
|
378
|
+
process.exit(1);
|
|
379
|
+
}
|
|
380
|
+
if (db) {
|
|
381
|
+
db.close();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FeedDatabase } from '../storage/database.js';
|
|
2
|
+
export interface DiscoveryCacheEntry {
|
|
3
|
+
key: string;
|
|
4
|
+
value: any;
|
|
5
|
+
expiresAt: number;
|
|
6
|
+
createdAt: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class DiscoveryCache {
|
|
9
|
+
private db;
|
|
10
|
+
private defaultTTLSeconds;
|
|
11
|
+
constructor(db: FeedDatabase, defaultTTLSeconds?: number);
|
|
12
|
+
get(url: string): any | undefined;
|
|
13
|
+
set(url: string, value: any, ttlSeconds?: number): void;
|
|
14
|
+
clear(): void;
|
|
15
|
+
getStats(): {
|
|
16
|
+
entries: number;
|
|
17
|
+
hitRate: number;
|
|
18
|
+
};
|
|
19
|
+
private getCacheKey;
|
|
20
|
+
isCached(url: string): boolean;
|
|
21
|
+
invalidate(url: string): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,GAAG,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,EAAE,EAAE,YAAY,EAAE,iBAAiB,GAAE,MAAY;IAK7D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAoBjC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvD,KAAK,IAAI,IAAI;IAIb,QAAQ,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAQhD,OAAO,CAAC,WAAW;IAInB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM9B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAI9B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export class DiscoveryCache {
|
|
2
|
+
db;
|
|
3
|
+
defaultTTLSeconds;
|
|
4
|
+
constructor(db, defaultTTLSeconds = 300) {
|
|
5
|
+
this.db = db;
|
|
6
|
+
this.defaultTTLSeconds = defaultTTLSeconds;
|
|
7
|
+
}
|
|
8
|
+
get(url) {
|
|
9
|
+
const key = this.getCacheKey(url);
|
|
10
|
+
const cached = this.db.getCache(key);
|
|
11
|
+
if (!cached) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
const expiresAt = cached.expiresAt;
|
|
15
|
+
const now = Math.floor(Date.now() / 1000);
|
|
16
|
+
if (expiresAt < now) {
|
|
17
|
+
this.db.setCache(key, Buffer.from(''), 1);
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const value = JSON.parse(cached.value.toString('utf-8'));
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
set(url, value, ttlSeconds) {
|
|
24
|
+
const key = this.getCacheKey(url);
|
|
25
|
+
const ttl = ttlSeconds ?? this.defaultTTLSeconds;
|
|
26
|
+
const expiresAt = Math.floor(Date.now() / 1000) + ttl;
|
|
27
|
+
const valueBuffer = Buffer.from(JSON.stringify(value), 'utf-8');
|
|
28
|
+
this.db.setCache(key, valueBuffer, ttl);
|
|
29
|
+
}
|
|
30
|
+
clear() {
|
|
31
|
+
this.db.clearCache();
|
|
32
|
+
}
|
|
33
|
+
getStats() {
|
|
34
|
+
const stats = this.db.getCacheStats();
|
|
35
|
+
return {
|
|
36
|
+
entries: stats.count,
|
|
37
|
+
hitRate: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
getCacheKey(url) {
|
|
41
|
+
return `discovery:${url}`;
|
|
42
|
+
}
|
|
43
|
+
isCached(url) {
|
|
44
|
+
const key = this.getCacheKey(url);
|
|
45
|
+
const cached = this.db.getCache(key);
|
|
46
|
+
return cached !== undefined;
|
|
47
|
+
}
|
|
48
|
+
invalidate(url) {
|
|
49
|
+
const key = this.getCacheKey(url);
|
|
50
|
+
this.db.setCache(key, Buffer.from(''), 1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,cAAc;IACjB,EAAE,CAAe;IACjB,iBAAiB,CAAS;IAElC,YAAY,EAAgB,EAAE,oBAA4B,GAAG;QAC3D,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC7C,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAErC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAE1C,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;YACpB,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1C,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,UAAmB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;QACtD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QACtC,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC;SACX,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,GAAW;QAC7B,OAAO,aAAa,GAAG,EAAE,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,MAAM,KAAK,SAAS,CAAC;IAC9B,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/core/discovery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAwIpE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAiD1F"}
|