Skip to content

Commit

Permalink
Merge pull request #9 from benVigie/feat/artcle-computing-feedback
Browse files Browse the repository at this point in the history
Article computing feedback
  • Loading branch information
benVigie authored Nov 28, 2024
2 parents e04de48 + 52a33fe commit 39e91ae
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
37 changes: 29 additions & 8 deletions src/epub_news.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Parser from "rss-parser";
import { DateTime } from "luxon";
import { EPub, EpubContentOptions, EpubOptions } from "@lesjoursfr/html-to-epub";
import createMediaSource from "./media_sources/media_source_factory.js";
import { ComputeArticlesResult } from "./media_sources/media_source.js";

const UNKNOWN_RSS_FEED_TITLE = "No feed title";
const LOCALE = "fr";
Expand All @@ -17,6 +18,20 @@ export interface Options {
details?: boolean;
}

export interface ArticlesFetchingResult {
title: string;
link: string;
success: boolean;
error?: string;
}

export interface EbookResult {
result: string;
title: string;
path: string;
articles: ArticlesFetchingResult[];
}

/**
* Describe article list
*/
Expand All @@ -29,9 +44,8 @@ export interface ArticlesList {
/**
* Rss articles formated from feed, with cover image and css
*/
export interface EpubArticlesData {
export interface EpubArticlesData extends ComputeArticlesResult {
feedTitle: string;
articles: EpubArticle[];
cover: string | undefined;
customCss: string | undefined;
}
Expand All @@ -44,12 +58,13 @@ export class NoMediaSourceError extends Error {}
*/
export default class EpubNews {
private _options: Options;
private _fetching: ArticlesFetchingResult[];

constructor(options: Options) {
constructor(options?: Options) {
// Default values
if (options.debug === undefined) options.debug = false;
if (options.details === undefined) options.details = false;
options = { debug: false, details: false, ...options };
this._options = options;
this._fetching = [];
}

/**
Expand Down Expand Up @@ -95,7 +110,7 @@ export default class EpubNews {

// Fetch and format epub data from the given article list
return {
articles: await mediaSource.computeArticlesFromNewsList(articles),
...(await mediaSource.computeArticlesFromNewsList(articles)),
feedTitle: mediaSource.feedTitle || UNKNOWN_RSS_FEED_TITLE,
cover: mediaSource.mediaSourceCover,
customCss: mediaSource.customCss,
Expand All @@ -120,7 +135,7 @@ export default class EpubNews {
customCss: string,
cover?: string,
description?: string,
): Promise<{ result: string }> {
): Promise<EbookResult> {
const css = fs.readFileSync(path.resolve(import.meta.dirname, "../epub.css"));

const epubOptions: EpubOptions = {
Expand All @@ -136,6 +151,12 @@ export default class EpubNews {
};

const epub = new EPub(epubOptions, filePath);
return epub.render();
const r = await epub.render();
return {
result: r.result,
title,
path: filePath,
articles: [],
};
}
}
33 changes: 27 additions & 6 deletions src/media_sources/media_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,25 @@ import chalk from "chalk";
import Parser from "rss-parser";
import ora, { Ora } from "ora";
import terminalLink from "terminal-link";
import { EpubContentOptions } from "@lesjoursfr/html-to-epub";
import { Options } from "../epub_news.js";
import { EpubArticle, Options } from "../epub_news.js";

/** Default trim article error */
export class TrimArticleError extends Error {}

/** Article fetching result */
export interface ArticlesFetchingResult {
title: string;
link: string;
success: boolean;
error?: string;
}

/** Compute articles data result, epub content and fetching result */
export interface ComputeArticlesResult {
epubContent: EpubArticle[];
results: ArticlesFetchingResult[];
}

/**
* Media source is the abstract class every media source must inherit from.
* It will manage the rss fetching, retrieve the news content and format it to be injected in the final ebook.
Expand Down Expand Up @@ -75,8 +88,8 @@ export abstract class MediaSource<T = { [key: string]: any }, U = { [key: string
* @param newsList The news list to parse
* @returns A list of EpubContentOptions ready to be injected in the ebook
*/
public async computeArticlesFromNewsList(newsList: Array<Parser.Item & U>): Promise<Array<EpubContentOptions>> {
const articles: Array<EpubContentOptions> = [];
public async computeArticlesFromNewsList(newsList: Array<Parser.Item & U>): Promise<ComputeArticlesResult> {
const result: ComputeArticlesResult = { epubContent: [], results: [] };

// Set fetch options before starting to retrieve articles
this.setFetchOptions();
Expand All @@ -91,11 +104,13 @@ export abstract class MediaSource<T = { [key: string]: any }, U = { [key: string
try {
// Try to parse the article. If we have something, add it to the ebook
const trimedArticle = this.trimArticleForEpub(news, article);
articles.push({
result.epubContent.push({
title: news.title,
data: trimedArticle,
author: news.creator,
});
result.results.push({ title: news.title, link: news.link, success: true });

if (this._options.details) {
this._spinner.suffixText = chalk.green("ok");
this._spinner.succeed();
Expand All @@ -107,12 +122,18 @@ export abstract class MediaSource<T = { [key: string]: any }, U = { [key: string
// If an error occurs, display the article link in console for information
const link = terminalLink(news.title, news.link);
if (this._options.details) this._spinner.warn(chalk.italic.gray(link));
result.results.push({
title: news.title,
link: news.link,
success: false,
error: (error as Error).toString(),
});
}
} else {
if (this._options.details) this._spinner.warn(chalk.italic.red("No title or link for this news, skip"));
}
}
return articles;
return result;
}

/***
Expand Down
2 changes: 1 addition & 1 deletion src/news_cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ async function main() {
// Retrieve and format articles
const epubData = await epub.getEpubDataFromArticles(rssFeed, feedList.articles);
// Add articles to our epub list
epubContent = epubContent.concat(epubData.articles);
epubContent = epubContent.concat(epubData.epubContent);
// Set cover and custom css if we need to
if (!epubCover) epubCover = epubData.cover;
if (epubData.customCss && !customCss.includes(epubData.customCss)) customCss += epubData.customCss;
Expand Down

0 comments on commit 39e91ae

Please sign in to comment.