feat: read subscriptions from an Atom feed when a page lists no dated links
This commit is contained in:
parent
b0b86ef5b1
commit
fa51d5793d
9 changed files with 411 additions and 4 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:actors/actors.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../mews/atom.dart';
|
||||
import '../../mews/document.dart';
|
||||
import '../../mews/parser.dart';
|
||||
|
||||
|
|
@ -31,6 +32,14 @@ class SubmitForm extends FetchCommand {
|
|||
final Map<String, String> fields;
|
||||
}
|
||||
|
||||
/// Fetch and read a subscribed page's Atom feed (spec 6.2). [url] is absolute
|
||||
/// and on the page's own site, which the parser has already checked.
|
||||
class FetchFeed extends FetchCommand {
|
||||
const FetchFeed({required this.url});
|
||||
|
||||
final String url;
|
||||
}
|
||||
|
||||
/// Parses a page's source without touching the network; used to prepare the
|
||||
/// neighboring pages that swipes reveal.
|
||||
class ParseSource extends FetchCommand {
|
||||
|
|
@ -44,6 +53,14 @@ sealed class FetchResult {
|
|||
const FetchResult();
|
||||
}
|
||||
|
||||
/// The posts an Atom feed lists.
|
||||
class FetchFeedOk extends FetchResult {
|
||||
const FetchFeedOk({required this.url, required this.entries});
|
||||
|
||||
final String url;
|
||||
final List<MewsEntry> entries;
|
||||
}
|
||||
|
||||
class FetchPageOk extends FetchResult {
|
||||
const FetchPageOk({
|
||||
required this.page,
|
||||
|
|
@ -103,6 +120,7 @@ class FetchHandler with Handler<FetchCommand, FetchResult> {
|
|||
await _fetchPage(url, etag, lastModified, cachedSource),
|
||||
SubmitForm(:final url, :final method, :final fields) =>
|
||||
await _submitForm(url, method, fields),
|
||||
FetchFeed(:final url) => await _fetchFeed(url),
|
||||
ParseSource(:final url, :final source) => _parse(source, url),
|
||||
};
|
||||
}
|
||||
|
|
@ -149,6 +167,28 @@ class FetchHandler with Handler<FetchCommand, FetchResult> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<FetchResult> _fetchFeed(String url) async {
|
||||
final http.Response response;
|
||||
try {
|
||||
response = await _client
|
||||
.get(Uri.parse(url), headers: {'User-Agent': _userAgent})
|
||||
.timeout(const Duration(seconds: 20));
|
||||
} catch (_) {
|
||||
return const FetchNetworkError();
|
||||
}
|
||||
if (response.statusCode != 200) {
|
||||
return FetchHttpStatusError(response.statusCode);
|
||||
}
|
||||
try {
|
||||
return FetchFeedOk(
|
||||
url: url,
|
||||
entries: parseAtomEntries(source: response.body, feedUrl: url),
|
||||
);
|
||||
} on MewsParseException catch (e) {
|
||||
return FetchParseError(e.message, response.body);
|
||||
}
|
||||
}
|
||||
|
||||
Future<FetchResult> _submitForm(String url, String method, Map<String, String> fields) async {
|
||||
final headers = {'User-Agent': _userAgent};
|
||||
final http.Response response;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue