kopia lustrzana https://gitlab.com/mysocialportal/relatica
Add initial JSON parsers for Friendica and Mastodon JSON formats
rodzic
bde1aab519
commit
4c180f7de8
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
}
|
Ładowanie…
Reference in New Issue