Files
Prisma/lib/backend/mappers/e621_mapper.dart
T
RarDog cd1a9ccc0c
Build and Release / Build Windows x64 (push) Has been cancelled
Build and Release / Build macOS (push) Has been cancelled
feat: add dedicated e621 tab in Favorites and fix comic post-not-found parsing (v3.7.1)
2026-09-05 20:19:27 +03:00

144 lines
4.5 KiB
Dart

import '../models/post.dart';
class E621Mapper {
static List<Post> postsFromResponse(
dynamic data, {
required String providerId,
required String providerName,
}) {
if (data is Map && data['post'] is Map) {
return [
postFromJson(
Map<String, dynamic>.from(data['post'] as Map),
providerId: providerId,
providerName: providerName,
),
];
}
final posts = data is Map ? (data['posts'] ?? data['post']) : data;
final items = posts is List
? posts
: (posts is Map ? [posts] : const []);
return items
.whereType<Map>()
.map((item) => postFromJson(
Map<String, dynamic>.from(item),
providerId: providerId,
providerName: providerName,
))
.toList();
}
static Post postFromJson(
Map<String, dynamic> json, {
required String providerId,
required String providerName,
}) {
final file = Map<String, dynamic>.from((json['file'] as Map?) ?? const {});
final preview =
Map<String, dynamic>.from((json['preview'] as Map?) ?? const {});
final sample =
Map<String, dynamic>.from((json['sample'] as Map?) ?? const {});
final score =
Map<String, dynamic>.from((json['score'] as Map?) ?? const {});
final tagsMap =
Map<String, dynamic>.from((json['tags'] as Map?) ?? const {});
final tagGroups = {
for (final entry in tagsMap.entries)
entry.key: List<String>.from((entry.value as List?) ?? const []),
}..removeWhere((_, value) => value.isEmpty);
final relationships = Map<String, dynamic>.from((json['relationships'] as Map?) ?? const {});
final parentId = relationships['parent_id']?.toString();
if (parentId != null && parentId.isNotEmpty && parentId != 'null') {
tagGroups['parent_id'] = [parentId];
}
final children = (relationships['children'] as List?)
?.map((e) => e?.toString() ?? '')
.where((s) => s.isNotEmpty && s != 'null')
.toList();
if (children != null && children.isNotEmpty) {
tagGroups['children'] = children;
}
final rawPools = (json['pools'] as List?)
?.map((e) => e?.toString() ?? '')
.where((s) => s.isNotEmpty)
.toList();
if (rawPools != null && rawPools.isNotEmpty) {
tagGroups['pools'] = rawPools;
}
final favCount = json['fav_count'];
if (favCount != null) {
tagGroups['fav_count'] = [favCount.toString()];
}
final desc = _string(json['description']);
if (desc.isNotEmpty) {
tagGroups['description'] = [desc];
}
final tags = tagGroups.values.expand((items) => items).toSet().toList();
final fileUrl = _string(file['url']);
return Post(
id: _string(json['id']),
providerId: providerId,
providerName: providerName,
previewUrl: _string(preview['url'] ?? sample['url'] ?? fileUrl),
sampleUrl: _string(sample['url'] ?? fileUrl),
fileUrl: fileUrl,
tags: tags,
rating: _rating(_string(json['rating'], fallback: 'unknown')),
width: _int(file['width']),
height: _int(file['height']),
source: _sources(json['sources']),
createdAt:
DateTime.tryParse(_string(json['created_at'])) ?? DateTime.now(),
fileType: _fileType(fileUrl, file['ext']),
score: _int(score['total'] ?? json['score']),
tagGroups: tagGroups,
);
}
static String _rating(String value) {
return switch (value.toLowerCase()) {
's' => 'safe',
'q' => 'questionable',
'e' => 'explicit',
_ => value,
};
}
static String? _sources(dynamic value) {
if (value is List && value.isNotEmpty) return value.first.toString();
final text = value?.toString();
return text == null || text.isEmpty ? null : text;
}
static int _int(dynamic value) {
if (value is int) return value;
if (value is num) return value.toInt();
return int.tryParse(value?.toString() ?? '') ?? 0;
}
static String _string(dynamic value, {String fallback = ''}) {
final text = value?.toString();
return text == null || text.isEmpty ? fallback : text;
}
static String _fileType(String url, dynamic fileExt) {
final lower = url.toLowerCase().split('?').first;
final ext = _string(fileExt).toLowerCase();
if (lower.endsWith('.webm') ||
lower.endsWith('.mp4') ||
ext == 'webm' ||
ext == 'mp4') {
return 'video';
}
if (lower.endsWith('.gif') || ext == 'gif') return 'gif';
if (lower.isEmpty) return 'unknown';
return 'image';
}
}