load trending images from tmdb at startup

- need TMDB_API_KEY as environment variable
- mount /cache for data persistence

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2025-11-17 23:21:01 +01:00
parent 4587901672
commit 4ce471599b
17 changed files with 305 additions and 10 deletions

View File

@@ -0,0 +1,7 @@
import 'package:cinema/feature/poster/domain/movie.dart';
abstract class ImageLoader {
Future<List<Movie>> getPosterURIs({String? language = 'de'});
Future<bool> downloadImages(Movie movie);
}

View File

@@ -0,0 +1,57 @@
import 'dart:io';
import 'package:cinema/common/dio_module.dart';
import 'package:cinema/common/domain/serializers.dart';
import 'package:cinema/feature/poster/data/repositories/image_loader.dart';
import 'package:cinema/feature/poster/domain/movie.dart';
import 'package:cinema/feature/poster/domain/tmdb_trending_response.dart';
import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
@Injectable(as: ImageLoader)
class TmDBImageLoader implements ImageLoader {
final Dio api;
final Dio images;
final String imageBaseUrl = 'https://image.tmdb.org/t/p/w500';
TmDBImageLoader(@Named(dioAPI) this.api, @Named(dioIMAGES) this.images);
@override
Future<List<Movie>> getPosterURIs({String? language = 'de'}) async {
final response = await api.get('/trending/movie/week?language=$language');
if (response.data != null) {
final data = serializers.deserializeWith(TmdbTrendingResponse.serializer, response.data);
return data?.results
.map(
(movie) => Movie(
(b) => b
..id = movie.id
..poster = movie.posterPath
..backdrop = movie.backdropPath,
),
)
.toList() ??
[];
}
return [];
}
@override
Future<bool> downloadImages(Movie movie) async {
await downloadImage(movie.poster, "cache/movie/${movie.id}/poster.png");
await downloadImage(movie.backdrop, "cache/movie/${movie.id}/backdrop.png");
return true;
}
Future<bool> downloadImage(String url, String filename) async {
final file = File(filename);
if (await file.exists()) {
return false;
}
await file.parent.create(recursive: true);
final response = await images.get(url, options: Options(responseType: ResponseType.bytes));
await file.writeAsBytes(response.data);
return true;
}
}