Files
plezy/lib/models/simkl/simkl_detail.dart
edde746 a33c423985 refactor(models): stop parsing wire fields and enum members nothing consumes
Parse-only DTO surface deleted across trackers and catalog models: quality-preset storageKey/fromStorage round-trips (persistence uses EnumPref on .name), PlexHome's placeholder identity fields (id stays — deriveHomeSecret reads it), SeerrUser.email/avatar, SimklSearchResult.endpointType, SimklDetail.type, SimklAllItemsEntry.status/isShow, TraktCatalogEntry.rank, CatalogItem.relevance, and the never-produced CatalogRankScope.favorited/.seasonal members with their label arms. Tracker root: OAuthProxyStart.expiresIn, TrackerSession.scope/isExpired, copyWith slimmed to its one real parameter, TrackerHttpClient.service. TrackerAccountStore.service and the trackerAccountStore() alias are live (persisted-blob validation, callers) and stay.
2026-08-17 19:02:24 +02:00

137 lines
4.1 KiB
Dart

import '../../utils/json_utils.dart';
import 'simkl_ids.dart';
import 'simkl_rating.dart';
import 'simkl_recommendation.dart';
import 'simkl_title.dart';
/// Rich movie, TV, or anime record returned by Simkl's detail endpoints.
class SimklDetail {
final String? title;
final int? year;
final String? animeType;
final String? originalTitle;
final String? englishTitle;
final List<String>? alternateTitles;
final String? url;
final String? poster;
final String? fanart;
final SimklIds ids;
final int? rank;
final String? dropRate;
final String? released;
final String? physicalRelease;
final String? firstAired;
final String? lastAired;
final SimklAirs? airs;
final int? runtime;
final String? certification;
final int? budget;
final int? revenue;
final String? overview;
final List<String>? genres;
final String? country;
final String? language;
final int? totalEpisodes;
final String? status;
final String? network;
final String? director;
final List<String>? studios;
final String? seasonNameYear;
final SimklRatings? ratings;
final String? trailer;
final List<SimklRecommendation> recommendations;
const SimklDetail({
this.title,
this.year,
this.animeType,
this.originalTitle,
this.englishTitle,
this.alternateTitles,
this.url,
this.poster,
this.fanart,
required this.ids,
this.rank,
this.dropRate,
this.released,
this.physicalRelease,
this.firstAired,
this.lastAired,
this.airs,
this.runtime,
this.certification,
this.budget,
this.revenue,
this.overview,
this.genres,
this.country,
this.language,
this.totalEpisodes,
this.status,
this.network,
this.director,
this.studios,
this.seasonNameYear,
this.ratings,
this.trailer,
this.recommendations = const [],
});
factory SimklDetail.fromJson(Map<String, dynamic> json) => SimklDetail(
title: json['title'] as String?,
year: flexibleInt(json['year']),
animeType: json['anime_type'] as String?,
originalTitle: json['title_romaji'] as String?,
englishTitle: json['en_title'] as String?,
alternateTitles: simklTitleNames(json['alt_titles']),
url: json['url'] as String?,
poster: json['poster'] as String?,
fanart: json['fanart'] as String?,
ids: parseFlexibleJsonObject(json['ids'], SimklIds.fromJson) ?? const SimklIds(),
rank: flexibleInt(json['rank']),
dropRate: json['droprate']?.toString(),
released: json['released'] as String?,
physicalRelease: (json['released_dvd'] ?? json['dvd_date']) as String?,
firstAired: json['first_aired'] as String?,
lastAired: json['last_aired'] as String?,
airs: parseFlexibleJsonObject(json['airs'], SimklAirs.fromJson),
runtime: flexibleInt(json['runtime']),
certification: json['certification'] as String?,
budget: flexibleInt(json['budget']),
revenue: flexibleInt(json['revenue']),
overview: json['overview'] as String?,
genres: flexibleStringList(json['genres']),
country: json['country'] as String?,
language: json['language'] as String?,
totalEpisodes: flexibleInt(json['total_episodes']),
status: json['status'] as String?,
network: json['network'] as String?,
director: json['director'] as String?,
studios: simklTitleNames(json['studios']),
seasonNameYear: json['season_name_year'] as String?,
ratings: parseFlexibleJsonObject(json['ratings'], SimklRatings.fromJson),
trailer: _firstTrailer(json['trailers']),
recommendations: parseFlexibleJsonList(json['users_recommendations'], SimklRecommendation.fromJson),
);
static String? _firstTrailer(Object? raw) {
for (final trailer in flexibleMapList(raw)) {
final youtube = trailer['youtube'];
if (youtube is String && youtube.trim().isNotEmpty) return youtube.trim();
}
return null;
}
}
class SimklAirs {
final String? day;
final String? time;
final String? timezone;
const SimklAirs({this.day, this.time, this.timezone});
factory SimklAirs.fromJson(Map<String, dynamic> json) =>
SimklAirs(day: json['day'] as String?, time: json['time'] as String?, timezone: json['timezone'] as String?);
}