fix: trakt ids conflicts for some series

This commit is contained in:
omkar 2025-01-11 11:08:41 +05:30
parent 144264d667
commit f13ff6fc9f
4 changed files with 54 additions and 32 deletions

View file

@ -338,9 +338,6 @@ class Meta extends LibraryItem {
return episode.tvdbId == episodeExternalIds['tvdb']; return episode.tvdbId == episodeExternalIds['tvdb'];
} }
print(episode.tvdbId);
print(episodeExternalIds?['tvdb']);
return nextEpisode == episode.episode && nextSeason == episode.season; return nextEpisode == episode.episode && nextSeason == episode.season;
}, },
); );

View file

@ -138,7 +138,11 @@ class _StremioItemSeasonSelectorState extends State<StremioItemSeasonSelector>
), ),
body: RenderStreamList( body: RenderStreamList(
service: widget.service!, service: widget.service!,
id: meta, id: meta.copyWith(
episodeExternalIds: {
"tvdb": episode.tvdbId,
},
),
season: currentSeason.toString(), season: currentSeason.toString(),
episode: episode.number?.toString(), episode: episode.number?.toString(),
shouldPop: widget.shouldPop, shouldPop: widget.shouldPop,

View file

@ -405,6 +405,7 @@ class _VideoViewerState extends State<VideoViewer> {
TraktService.instance!.stopScrobbling( TraktService.instance!.stopScrobbling(
meta: widget.meta as types.Meta, meta: widget.meta as types.Meta,
progress: currentProgressInPercentage, progress: currentProgressInPercentage,
shouldClearCache: true,
); );
} }

View file

@ -22,10 +22,6 @@ class TraktService {
static const String _baseUrl = 'https://api.trakt.tv'; static const String _baseUrl = 'https://api.trakt.tv';
static const String _apiVersion = '2'; static const String _apiVersion = '2';
static const int _authedPostLimit = 100;
static const int _authedGetLimit = 1000;
static const Duration _rateLimitWindow = Duration(minutes: 5);
final refetchKey = BehaviorSubject<List<String>>(); final refetchKey = BehaviorSubject<List<String>>();
static const Duration _cacheRevalidationInterval = Duration(hours: 1); static const Duration _cacheRevalidationInterval = Duration(hours: 1);
@ -34,10 +30,6 @@ class TraktService {
static TraktService? get instance => _instance; static TraktService? get instance => _instance;
static BaseConnectionService? stremioService; static BaseConnectionService? stremioService;
int _postRequestCount = 0;
int _getRequestCount = 0;
DateTime _lastRateLimitReset = DateTime.now();
Map<String, dynamic> _cache = {}; Map<String, dynamic> _cache = {};
saveCacheToDisk() { saveCacheToDisk() {
@ -82,7 +74,6 @@ class TraktService {
_instance?._cache = result?.data ?? {}; _instance?._cache = result?.data ?? {};
// Start cache revalidation timer
_instance!._startCacheRevalidation(); _instance!._startCacheRevalidation();
} }
@ -103,7 +94,8 @@ class TraktService {
final connection = ConnectionResponse( final connection = ConnectionResponse(
connection: Connection.fromRecord(model_), connection: Connection.fromRecord(model_),
connectionTypeRecord: ConnectionTypeRecord.fromRecord( connectionTypeRecord: ConnectionTypeRecord.fromRecord(
model_.get<RecordModel>("expand.type")), model_.get<RecordModel>("expand.type"),
),
); );
stremioService = BaseConnectionService.connectionById(connection); stremioService = BaseConnectionService.connectionById(connection);
@ -192,18 +184,40 @@ class TraktService {
'year': meta.year, 'year': meta.year,
'ids': { 'ids': {
'imdb': meta.imdbId ?? meta.id, 'imdb': meta.imdbId ?? meta.id,
...(meta.episodeExternalIds ?? {}), if (meta.tvdbId != null) 'tvdb': meta.tvdbId,
}, },
}, },
}; };
} else { } else {
final Map<String, dynamic> episodeExternalIds =
meta.episodeExternalIds ?? {};
final isEmpty = episodeExternalIds.keys.isEmpty;
if (!isEmpty) {
return {
"episode": {
"ids": meta.episodeExternalIds,
},
};
}
if (meta.currentVideo?.id != null) {
return {
"episode": {
"ids": {
"imdb": meta.currentVideo?.id,
},
},
};
}
return { return {
"show": { "show": {
"title": meta.name, "title": meta.name,
"year": meta.year, "year": meta.year,
"ids": { "ids": {
"imdb": meta.imdbId ?? meta.id, "imdb": meta.imdbId ?? meta.id,
...(meta.episodeExternalIds ?? {}),
} }
}, },
"episode": { "episode": {
@ -629,8 +643,6 @@ class TraktService {
try { try {
_logger.info('Starting scrobbling for ${meta.type} with ID: ${meta.id}'); _logger.info('Starting scrobbling for ${meta.type} with ID: ${meta.id}');
print(_buildObjectForMeta(meta));
final response = await http.post( final response = await http.post(
Uri.parse('$_baseUrl/scrobble/start'), Uri.parse('$_baseUrl/scrobble/start'),
headers: headers, headers: headers,
@ -640,6 +652,12 @@ class TraktService {
}), }),
); );
if (response.statusCode == 404) {
_logger.severe('Failed to start scrobbling: ${response.statusCode}');
_logger.severe("${_buildObjectForMeta(meta)}");
return;
}
if (response.statusCode != 201) { if (response.statusCode != 201) {
_logger.severe('Failed to start scrobbling: ${response.statusCode}'); _logger.severe('Failed to start scrobbling: ${response.statusCode}');
throw Exception('Failed to start scrobbling'); throw Exception('Failed to start scrobbling');
@ -663,8 +681,6 @@ class TraktService {
return; return;
} }
print(_buildObjectForMeta(meta));
final cacheKey = '${meta.id}_pauseScrobbling'; final cacheKey = '${meta.id}_pauseScrobbling';
_activeScrobbleRequests[cacheKey]?.completeError('Cancelled'); _activeScrobbleRequests[cacheKey]?.completeError('Cancelled');
@ -703,7 +719,9 @@ class TraktService {
body: json.encode(body), body: json.encode(body),
); );
if (response.statusCode == 201) { if (response.statusCode == 404) {
_logger.warning('could not find episode');
} else if (response.statusCode == 201) {
_logger.info('POST request successful'); _logger.info('POST request successful');
return; return;
} else if (response.statusCode == 429) { } else if (response.statusCode == 429) {
@ -735,6 +753,7 @@ class TraktService {
Future<void> stopScrobbling({ Future<void> stopScrobbling({
required Meta meta, required Meta meta,
required double progress, required double progress,
bool shouldClearCache = false,
}) async { }) async {
if (!isEnabled()) { if (!isEnabled()) {
_logger.info('Trakt integration is not enabled'); _logger.info('Trakt integration is not enabled');
@ -758,19 +777,20 @@ class TraktService {
}, },
); );
_cache.remove('$_baseUrl/sync/watched/shows'); if (shouldClearCache) {
_cache.remove('$_baseUrl/sync/playback'); _cache.remove('$_baseUrl/sync/watched/shows');
_cache.remove('$_baseUrl/sync/playback');
final keys = [ final keys = [
"continue_watching", "continue_watching",
if (meta.type == "series") "up_next_series", if (meta.type == "series") "up_next_series",
]; ];
refetchKey.add(keys);
refetchKey.add(keys); _logger.info(
"pushing refetch key ${keys.join(", ")} still in cache ${_cache.keys.join(", ")}",
_logger.info( );
"pushing refetch key ${keys.join(", ")} still in cache ${_cache.keys.join(", ")}", }
);
} catch (e, stack) { } catch (e, stack) {
_logger.severe('Error stopping scrobbling: $e', stack); _logger.severe('Error stopping scrobbling: $e', stack);
rethrow; rethrow;