@@ -75,7 +75,11 @@ def _process_tv(self, payload, user, ids):
7575 episode_number ,
7676 )
7777 if mal_id :
78- logger .info ("Detected anime episode with MAL ID: %s" , mal_id )
78+ logger .info (
79+ "Detected anime episode via MAL ID: %s, Episode: %d" ,
80+ mal_id ,
81+ episode_offset ,
82+ )
7983 self ._handle_anime (mal_id , episode_offset , payload , user )
8084 return
8185
@@ -323,17 +327,45 @@ def _handle_tv_episode(
323327 episode_item = season_instance .get_episode_item (episode_number , season_metadata )
324328
325329 if self ._is_played (payload ):
326- app .models .Episode .objects .create (
327- item = episode_item ,
328- related_season = season_instance ,
329- end_date = timezone .now ().replace (second = 0 , microsecond = 0 ),
330- )
331- logger .info (
332- "Marked episode as played: %s S%02dE%02d" ,
333- tv_metadata ["title" ],
334- season_number ,
335- episode_number ,
330+ now = timezone .now ().replace (second = 0 , microsecond = 0 )
331+ latest_episode = (
332+ app .models .Episode .objects .filter (
333+ item = episode_item ,
334+ related_season = season_instance ,
335+ )
336+ .order_by ("-end_date" )
337+ .first ()
336338 )
339+
340+ should_create = True
341+ # check for duplicate episode records,
342+ # sometimes webhooks are triggered multiple times #689
343+ if latest_episode and latest_episode .end_date :
344+ time_diff = abs ((now - latest_episode .end_date ).total_seconds ())
345+ threshold = 5
346+ if time_diff < threshold :
347+ should_create = False
348+ logger .info (
349+ "Skipping duplicate episode record "
350+ "(time difference: %d seconds): %s S%02dE%02d" ,
351+ time_diff ,
352+ tv_metadata ["title" ],
353+ season_number ,
354+ episode_number ,
355+ )
356+
357+ if should_create :
358+ app .models .Episode .objects .create (
359+ item = episode_item ,
360+ related_season = season_instance ,
361+ end_date = now ,
362+ )
363+ logger .info (
364+ "Marked episode as played: %s S%02dE%02d" ,
365+ tv_metadata ["title" ],
366+ season_number ,
367+ episode_number ,
368+ )
337369 else :
338370 logger .info (
339371 "Episode not marked as played: %s S%02dE%02d" ,
0 commit comments