feat: add sqlite catalog web app
This commit is contained in:
+101
@@ -0,0 +1,101 @@
|
||||
import express from 'express';
|
||||
import { CatalogDatabase } from '../database/store.js';
|
||||
import { dashboard, page, table } from './views.js';
|
||||
|
||||
export function createWebApp(databasePath: string) {
|
||||
const app = express();
|
||||
|
||||
app.get('/', (_req, res, next) => {
|
||||
withDatabase(databasePath, (db) => res.send(dashboard(db.dashboardCounts()))).catch(next);
|
||||
});
|
||||
|
||||
app.get('/links', (_req, res, next) => {
|
||||
withDatabase(databasePath, (db) =>
|
||||
res.send(
|
||||
page(
|
||||
'Links',
|
||||
`<h1>Links</h1>${table(db.contentLinks(), [
|
||||
['newsletter', 'Newsletter'],
|
||||
['issueDate', 'Issue Date'],
|
||||
['category', 'Category'],
|
||||
['title', 'Title'],
|
||||
['url', 'URL'],
|
||||
['description', 'Description']
|
||||
])}`
|
||||
)
|
||||
)
|
||||
).catch(next);
|
||||
});
|
||||
|
||||
app.get('/sponsors', (_req, res, next) => {
|
||||
withDatabase(databasePath, (db) =>
|
||||
res.send(
|
||||
page(
|
||||
'Sponsored Links',
|
||||
`<h1>Sponsored Links</h1>${table(db.sponsoredLinks(), [
|
||||
['newsletter', 'Newsletter'],
|
||||
['sponsor', 'Sponsor'],
|
||||
['description', 'Description']
|
||||
])}`
|
||||
)
|
||||
)
|
||||
).catch(next);
|
||||
});
|
||||
|
||||
app.get('/dead-links', (_req, res, next) => {
|
||||
withDatabase(databasePath, (db) =>
|
||||
res.send(
|
||||
page(
|
||||
'Dead Links',
|
||||
`<h1>Dead Links</h1>${table(db.deadLinks(), [
|
||||
['url', 'URL'],
|
||||
['status', 'Status'],
|
||||
['source', 'Source'],
|
||||
['date', 'Date']
|
||||
])}`
|
||||
)
|
||||
)
|
||||
).catch(next);
|
||||
});
|
||||
|
||||
app.get('/runs', (_req, res, next) => {
|
||||
withDatabase(databasePath, (db) =>
|
||||
res.send(
|
||||
page(
|
||||
'Runs',
|
||||
`<h1>Runs</h1>${table(db.runs(), [
|
||||
['started_at', 'Started'],
|
||||
['mode', 'Mode'],
|
||||
['newsletters_processed', 'Newsletters'],
|
||||
['links_extracted', 'Links'],
|
||||
['sponsors', 'Sponsors'],
|
||||
['dead_links', 'Dead Links'],
|
||||
['errors', 'Errors']
|
||||
])}`
|
||||
)
|
||||
)
|
||||
).catch(next);
|
||||
});
|
||||
|
||||
app.use(
|
||||
(error: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
|
||||
console.error(error);
|
||||
res.status(500).send(page('Error', '<h1>Error</h1><p>Something went wrong.</p>'));
|
||||
}
|
||||
);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
async function withDatabase(
|
||||
databasePath: string,
|
||||
callback: (database: CatalogDatabase) => void
|
||||
): Promise<void> {
|
||||
const db = new CatalogDatabase(databasePath);
|
||||
try {
|
||||
db.migrate();
|
||||
callback(db);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user