background fetch running

This commit is contained in:
Fabian Freund
2025-03-05 14:27:13 +01:00
parent 20bdc4df3e
commit 70d1c1b50e
62 changed files with 898 additions and 173 deletions
@@ -0,0 +1,51 @@
import 'package:collection/collection.dart';
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:lensai/core/logger.dart';
import 'package:lensai/extensions/nullable.dart';
import 'package:lensai/features/web_feed/data/models/feed_article.dart';
import 'package:lensai/features/web_feed/data/providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'article_content_processor.g.dart';
@Riverpod(keepAlive: true)
class ArticleContentProcessorService extends _$ArticleContentProcessorService {
@override
void build() {
final db = ref.watch(feedDatabaseProvider);
final processSub = db.articleDao.getUnprocessedArticles().watch().listen((
articles,
) async {
try {
final content = await GeckoBrowserExtensionService.turndownHtml(
articles.map((article) => article.contentHtml ?? '').toList(),
);
final summary = await GeckoBrowserExtensionService.turndownHtml(
articles.map((article) => article.summaryHtml ?? '').toList(),
);
await db.articleDao.updateArticleContent(
articles
.mapIndexed(
(index, article) => article.copyWith(
contentMarkdown: content[index].markdown.whenNotEmpty,
contentPlain: content[index].plain.whenNotEmpty,
summaryMarkdown: summary[index].markdown.whenNotEmpty,
summaryPlain: summary[index].plain.whenNotEmpty,
),
)
.toList(),
);
logger.i('Processed ${articles.length} articles');
} catch (e, s) {
logger.e('Error processing articles', error: e, stackTrace: s);
}
});
ref.onDispose(() async {
await processSub.cancel();
});
}
}
@@ -0,0 +1,28 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'article_content_processor.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$articleContentProcessorServiceHash() =>
r'182cd89e38a0a9a86b7425c16ad2bd1fc39c6704';
/// See also [ArticleContentProcessorService].
@ProviderFor(ArticleContentProcessorService)
final articleContentProcessorServiceProvider =
NotifierProvider<ArticleContentProcessorService, void>.internal(
ArticleContentProcessorService.new,
name: r'articleContentProcessorServiceProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$articleContentProcessorServiceHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$ArticleContentProcessorService = Notifier<void>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
@@ -28,7 +28,7 @@ class FeedReader extends _$FeedReader {
final parser = FeedParser.parse(url: url, xmlString: response.body);
final result = FeedParseResult(
feedData: parser.readGeneralData(),
articleData: await parser.readArticles(),
articleData: parser.readArticles(),
);
return result.toJson();
@@ -6,7 +6,7 @@ part of 'feed_reader.dart';
// RiverpodGenerator
// **************************************************************************
String _$feedReaderHash() => r'67b09485e40c522108709ca32b9c624b4db2446b';
String _$feedReaderHash() => r'301e01fa831c58723dc0ab118496f4fb34c38610';
/// See also [FeedReader].
@ProviderFor(FeedReader)