Add initial JSON parsers for Friendica and Mastodon JSON formats

codemagic-setup
Hank Grabowski 2022-11-08 20:24:54 -06:00
rodzic bde1aab519
commit 4c180f7de8
6 zmienionych plików z 202 dodań i 30 usunięć

Wyświetl plik

@ -0,0 +1,16 @@
enum AttachmentMediaType {
unknown,
image,
video;
static AttachmentMediaType parse(String? text) {
if (text == null) {
return AttachmentMediaType.unknown;
}
return AttachmentMediaType.values.firstWhere(
(e) => e.name == text,
orElse: () => unknown,
);
}
}

Wyświetl plik

@ -0,0 +1,20 @@
import '../../models/connection.dart';
extension ConnectionFriendicaExtensions on Connection {
static Connection fromJson(Map<String, dynamic> json) {
final status = (json['following'] ?? '') == 'true'
? ConnectionStatus.youFollowThem
: ConnectionStatus.none;
final name = json['name'] ?? '';
final id = json['id_str'] ?? '';
final profileUrl = Uri.parse(json['url'] ?? '');
final network = json['network'] ?? 'unkn';
return Connection(
status: status,
name: name,
id: id,
profileUrl: profileUrl,
network: network);
}
}

Wyświetl plik

@ -0,0 +1,28 @@
import '../../models/attachment_media_type_enum.dart';
import '../../models/media_attachment.dart';
extension MediaAttachmentFriendicaExtensions on MediaAttachment {
static MediaAttachment fromJson(Map<String, dynamic> json) {
final uri = Uri.parse(json['url']);
const creationTimestamp = 0;
final metadata = (json['metadata'] as Map<String, dynamic>? ?? {})
.map((key, value) => MapEntry(key, value.toString()));
final explicitType = (json['mimetype'] ?? '').startsWith('image')
? AttachmentMediaType.image
: (json['mimetype'] ?? '').startsWith('video')
? AttachmentMediaType.video
: AttachmentMediaType.unknown;
final thumbnailUri = Uri();
const title = '';
const description = '';
return MediaAttachment(
uri: uri,
creationTimestamp: creationTimestamp,
metadata: metadata,
thumbnailUri: thumbnailUri,
title: title,
explicitType: explicitType,
description: description);
}
}

Wyświetl plik

@ -0,0 +1,68 @@
import 'package:flutter_portal/serializers/friendica/connection_friendica_extensions.dart';
import 'package:flutter_portal/serializers/friendica/media_attachment_friendica_extensions.dart';
import 'package:logging/logging.dart';
import '../../models/location_data.dart';
import '../../models/timeline_entry.dart';
import '../../utils/dateutils.dart';
final _logger = Logger('FriendicaTimelineEntrySerializer');
extension TimelineEntryFriendicaExtensions on TimelineEntry {
static TimelineEntry fromJson(Map<String, dynamic> json) {
final int timestamp = json.containsKey('created_at')
? OffsetDateTimeUtils.epochSecTimeFromFriendicaString(
json['created_at'])
.fold(
onSuccess: (value) => value,
onError: (error) {
_logger.severe("Couldn't read date time string: $error");
return 0;
})
: 0;
final id = json['id_str'] ?? '';
final isReshare = json.containsKey('retweeted_status');
final parentId = json['in_reply_to_status_id_str'] ?? '';
final parentAuthor = json['in_reply_to_screen_name'] ?? '';
final parentAuthorId = json['in_reply_to_user_id_str'] ?? '';
final body = json['friendica_html'] ?? '';
final author = json['user']['name'];
final authorId = json['user']['id_str'];
final title = json['friendica_title'] ?? '';
final externalLink = json['external_url'] ?? '';
final actualLocationData = LocationData();
final modificationTimestamp = timestamp;
final backdatedTimestamp = timestamp;
final mediaAttachments = (json['attachments'] as List<dynamic>? ?? [])
.map((j) => MediaAttachmentFriendicaExtensions.fromJson(j))
.toList();
final likes =
(json['friendica_activities']?['like'] as List<dynamic>? ?? [])
.map((json) => ConnectionFriendicaExtensions.fromJson(json))
.toList();
final dislikes =
(json['friendica_activities']?['dislike'] as List<dynamic>? ?? [])
.map((json) => ConnectionFriendicaExtensions.fromJson(json))
.toList();
return TimelineEntry(
creationTimestamp: timestamp,
modificationTimestamp: modificationTimestamp,
backdatedTimestamp: backdatedTimestamp,
locationData: actualLocationData,
body: body,
isReshare: isReshare,
id: id,
parentId: parentId,
parentAuthorId: parentAuthorId,
externalLink: externalLink,
author: author,
authorId: authorId,
parentAuthor: parentAuthor,
title: title,
likes: likes,
dislikes: dislikes,
mediaAttachments: mediaAttachments,
);
}
}

Wyświetl plik

@ -0,0 +1,70 @@
import 'package:logging/logging.dart';
import '../../models/engagement_summary.dart';
import '../../models/link_data.dart';
import '../../models/location_data.dart';
import '../../models/media_attachment.dart';
import '../../models/timeline_entry.dart';
import '../../utils/dateutils.dart';
final _logger = Logger('TimelineEntryMastodonExtensions');
extension TimelineEntryMastodonExtensions on TimelineEntry {
static TimelineEntry fromJson(Map<String, dynamic> json) {
final int timestamp = json.containsKey('created_at')
? OffsetDateTimeUtils.epochSecTimeFromTimeZoneString(json['created_at'])
.fold(
onSuccess: (value) => value,
onError: (error) {
_logger.severe("Couldn't read date time string: $error");
return 0;
})
: 0;
final id = json['id'] ?? '';
final isReshare = json.containsKey('reblogged');
final parentId = json['in_reply_to_id'] ?? '';
final parentAuthor = json['in_reply_to_account_id'] ?? '';
final parentAuthorId = json['in_reply_to_account_id'] ?? '';
final body = json['content'] ?? '';
final author = json['account']['acct'];
final authorId = json['account']['id'];
const title = '';
final externalLink = json['uri'] ?? '';
final actualLocationData = LocationData();
final modificationTimestamp = timestamp;
final backdatedTimestamp = timestamp;
final linkData = json['card'] == null
? <LinkData>[]
: [LinkData.fromMastodonJson(json['card'])];
final mediaAttachments = (json['media_attachments'] as List<dynamic>? ?? [])
.map((json) => MediaAttachment.fromMastodonJson(json))
.toList();
final favoritesCount = json['favorites_count'] ?? 0;
final repliesCount = json['replies_count'] ?? 0;
final rebloggedCount = json['reblogs_count'] ?? 0;
final engagementSummary = EngagementSummary(
favoritesCount: favoritesCount,
rebloggedCount: rebloggedCount,
repliesCount: repliesCount,
);
return TimelineEntry(
creationTimestamp: timestamp,
modificationTimestamp: modificationTimestamp,
backdatedTimestamp: backdatedTimestamp,
locationData: actualLocationData,
body: body,
isReshare: isReshare,
id: id,
parentId: parentId,
parentAuthorId: parentAuthorId,
externalLink: externalLink,
author: author,
authorId: authorId,
parentAuthor: parentAuthor,
title: title,
links: linkData,
mediaAttachments: mediaAttachments,
engagementSummary: engagementSummary,
);
}
}

Wyświetl plik

@ -1,30 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_portal/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}