Files
Prisma/lib/backend/mappers/danbooru_mapper.dart
T

107 lines
3.4 KiB
Dart

import '../models/post.dart';
class DanbooruMapper {
static List<Post> postsFromResponse(
dynamic data, {
required String providerId,
required String providerName,
}) {
final items = data is List ? data : 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 fileUrl = _string(json['file_url'] ?? json['large_file_url']);
final sampleUrl =
_string(json['large_file_url'] ?? json['sample_file_url'] ?? fileUrl);
final previewUrl = _string(json['preview_file_url'] ?? sampleUrl);
final tagGroups = _tagGroups(json);
final tags = tagGroups.isEmpty
? _tags(json['tag_string'] ?? json['tags'])
: tagGroups.values.expand((items) => items).toSet().toList();
return Post(
id: _string(json['id']),
providerId: providerId,
providerName: providerName,
previewUrl: previewUrl,
sampleUrl: sampleUrl,
fileUrl: fileUrl,
tags: tags,
rating: _string(json['rating'], fallback: 'unknown'),
width: _int(json['image_width'] ?? json['width']),
height: _int(json['image_height'] ?? json['height']),
source: _nullableString(json['source']),
createdAt:
DateTime.tryParse(_string(json['created_at'])) ?? DateTime.now(),
fileType: _fileType(fileUrl, json['file_ext']),
score: _int(json['score']),
tagGroups: tagGroups.isEmpty ? {'general': tags} : tagGroups,
);
}
static List<String> _tags(dynamic value) {
if (value is List) return value.map((tag) => tag.toString()).toList();
return _string(value)
.split(RegExp(r'\s+'))
.where((tag) => tag.trim().isNotEmpty)
.toSet()
.toList();
}
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? _nullableString(dynamic value) {
final text = value?.toString();
return text == null || text.isEmpty ? null : 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';
}
static Map<String, List<String>> _tagGroups(Map<String, dynamic> json) {
final groups = <String, List<String>>{};
void add(String key, dynamic value) {
final tags = _tags(value);
if (tags.isNotEmpty) groups[key] = tags;
}
add('general', json['tag_string_general']);
add('artist', json['tag_string_artist']);
add('copyright', json['tag_string_copyright']);
add('character', json['tag_string_character']);
add('meta', json['tag_string_meta']);
return groups;
}
}