speed up series update
This commit is contained in:
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import '../../core/api/backend_api.dart';
|
||||
import '../../core/config.dart';
|
||||
import '../../core/async_utils.dart';
|
||||
import '../shared/providers.dart';
|
||||
|
||||
class ImportScreen extends ConsumerStatefulWidget {
|
||||
@@ -18,6 +20,7 @@ class _ImportScreenState extends ConsumerState<ImportScreen> {
|
||||
TextEditingController(text: '1396, 1399'); // Breaking Bad, GoT
|
||||
String _log = '';
|
||||
bool _busy = false;
|
||||
bool _cancel = false;
|
||||
|
||||
void _append(String msg) => setState(() => _log += '$msg\n');
|
||||
|
||||
@@ -44,7 +47,7 @@ class _ImportScreenState extends ConsumerState<ImportScreen> {
|
||||
}
|
||||
|
||||
Future<void> _importShows() async {
|
||||
setState(() => _busy = true);
|
||||
setState(() { _busy = true; _cancel = false; });
|
||||
final tmdb = ref.read(tmdbApiProvider);
|
||||
final backend = ref.read(backendApiProvider);
|
||||
|
||||
@@ -54,6 +57,7 @@ class _ImportScreenState extends ConsumerState<ImportScreen> {
|
||||
.map(int.parse);
|
||||
|
||||
for (final showId in ids) {
|
||||
if (_cancel) break;
|
||||
try {
|
||||
_append('Serie $showId: TMDB laden …');
|
||||
final showJson = await tmdb.getShow(showId);
|
||||
@@ -62,27 +66,51 @@ class _ImportScreenState extends ConsumerState<ImportScreen> {
|
||||
await backend.upsertShow(showJson);
|
||||
_append('Serie $showId: Show OK ✓');
|
||||
|
||||
final seasons = (showJson['seasons'] as List? ?? const [])
|
||||
final seasonNos = (showJson['seasons'] as List? ?? const [])
|
||||
.where((s) => (s['season_number'] ?? 0) is int)
|
||||
.cast<Map<String, dynamic>>();
|
||||
.map((s) => (s as Map<String, dynamic>)['season_number'] as int)
|
||||
.where((n) => n >= 0)
|
||||
.toList();
|
||||
|
||||
for (final s in seasons) {
|
||||
final seasonNo = (s['season_number'] as num).toInt();
|
||||
if (seasonNo < 0) continue;
|
||||
_append(' S$seasonNo: TMDB Season laden …');
|
||||
// Fetch all seasons (limited concurrency)
|
||||
final seasonsJson = <int, Map<String, dynamic>>{};
|
||||
await runChunked<int>(
|
||||
seasonNos,
|
||||
AppConfig.tmdbSeasonFetchConcurrency,
|
||||
(sNo) async {
|
||||
if (_cancel) return;
|
||||
final sj = await tmdb.getSeason(showId, sNo);
|
||||
seasonsJson[sNo] = sj;
|
||||
},
|
||||
isCancelled: () => _cancel,
|
||||
);
|
||||
|
||||
final seasonJson = await tmdb.getSeason(showId, seasonNo);
|
||||
final dbShowId = await _getDbShowIdByTmdb(backend, showId);
|
||||
final dbSeasonId = await backend.upsertSeason(dbShowId, seasonJson);
|
||||
final dbShowId = await _getDbShowIdByTmdb(backend, showId);
|
||||
// Bulk upsert seasons and get IDs
|
||||
Map<int,int> seasonIds = const {};
|
||||
try {
|
||||
seasonIds = await backend.upsertSeasonsBulk(dbShowId, seasonsJson.values.toList());
|
||||
} catch (_) {
|
||||
final m = <int,int>{};
|
||||
for (final entry in seasonsJson.entries) { final id = await backend.upsertSeason(dbShowId, entry.value); m[entry.key] = id; }
|
||||
seasonIds = m;
|
||||
}
|
||||
|
||||
_append(' S$seasonNo: Season OK (db:$dbSeasonId)');
|
||||
|
||||
final eps = (seasonJson['episodes'] as List? ?? const [])
|
||||
.cast<Map<String, dynamic>>();
|
||||
for (final e in eps) {
|
||||
await backend.upsertEpisode(dbSeasonId, e);
|
||||
for (final entry in seasonsJson.entries) {
|
||||
if (_cancel) break;
|
||||
final sNo = entry.key; final seasonJson = entry.value; final dbSeasonId = seasonIds[sNo]; if (dbSeasonId == null) continue;
|
||||
_append(' S$sNo: upserting episodes …');
|
||||
final eps = (seasonJson['episodes'] as List? ?? const []).cast<Map<String, dynamic>>();
|
||||
try { await backend.upsertEpisodesBulk(dbSeasonId, eps); }
|
||||
catch (_) {
|
||||
await runChunked<Map<String, dynamic>>(
|
||||
eps,
|
||||
AppConfig.dbEpisodeUpsertConcurrency,
|
||||
(e) async { if (_cancel) return; await backend.upsertEpisode(dbSeasonId, e); },
|
||||
isCancelled: () => _cancel,
|
||||
);
|
||||
}
|
||||
_append(' S$seasonNo: ${eps.length} Episoden OK ✓');
|
||||
_append(' S$sNo: ${eps.length} Episoden OK ✓');
|
||||
}
|
||||
} catch (e) {
|
||||
// 👇 Hier kommt der erweiterte Catch hin!
|
||||
@@ -139,6 +167,12 @@ class _ImportScreenState extends ConsumerState<ImportScreen> {
|
||||
onPressed: _busy ? null : _importShows,
|
||||
child: const Text('Import Serien'),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (_busy)
|
||||
TextButton(
|
||||
onPressed: () => setState(() => _cancel = true),
|
||||
child: const Text('Abbrechen'),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Reference in New Issue
Block a user