1616 find_item_across_buckets ,
1717 retry_on_lock ,
1818)
19- from integrations .models import SonarrAccount
19+ from integrations .models import SonarrInstance
2020from integrations .source_sync import (
2121 remove_collection_source_state ,
2222 upsert_collection_source_state ,
@@ -67,34 +67,39 @@ def episodes(self, series_id):
6767 return self ._request ("/api/v3/episode" , params = {"seriesId" : series_id })
6868
6969
70- def importer (identifier , user , mode ):
70+ def importer (identifier , user , mode , instance_id = None ):
7171 """Import Sonarr collection ownership."""
72- return SonarrImporter (user ).import_data ()
72+ instance = (
73+ SonarrInstance .objects .get (pk = instance_id , user = user ) if instance_id else None
74+ )
75+ return SonarrImporter (user , instance = instance ).import_data ()
7376
7477
7578class SonarrImporter :
7679 """Import collection data from Sonarr."""
7780
78- def __init__ (self , user ):
79- """Bind the importer to a user with a connected Sonarr account ."""
81+ def __init__ (self , user , instance = None ):
82+ """Bind the importer to a user with a connected Sonarr instance ."""
8083 self .user = user
81- try :
82- self .account = user .sonarr_account
83- except SonarrAccount .DoesNotExist as error :
84+ if instance is not None :
85+ self .instance = instance
86+ else :
87+ self .instance = user .sonarr_instances .first ()
88+ if self .instance is None :
8489 msg = "Connect Sonarr before importing"
85- raise MediaImportError (msg ) from error
90+ raise MediaImportError (msg )
8691
8792 try :
88- api_key = decrypt_or_raise (self .account .api_key )
93+ api_key = decrypt_or_raise (self .instance .api_key )
8994 except MediaImportError as error :
90- self .account .connection_broken = True
91- self .account .last_error_message = str (error )
92- self .account .save (
95+ self .instance .connection_broken = True
96+ self .instance .last_error_message = str (error )
97+ self .instance .save (
9398 update_fields = ["connection_broken" , "last_error_message" , "updated_at" ],
9499 )
95100 raise
96101
97- self .client = SonarrClient (self .account .base_url , api_key )
102+ self .client = SonarrClient (self .instance .base_url , api_key )
98103 self .warnings = []
99104
100105 def import_data (self ):
@@ -104,9 +109,9 @@ def import_data(self):
104109 try :
105110 series_rows = self .client .series ()
106111 except MediaImportError as error :
107- self .account .connection_broken = True
108- self .account .last_error_message = str (error )
109- self .account .save (
112+ self .instance .connection_broken = True
113+ self .instance .last_error_message = str (error )
114+ self .instance .save (
110115 update_fields = ["connection_broken" , "last_error_message" , "updated_at" ],
111116 )
112117 raise
@@ -132,10 +137,10 @@ def import_data(self):
132137 imported_counts [item .media_type ] += 1
133138 imported_counts ["updated" ] += 1
134139
135- self .account .last_sync_at = timezone .now ()
136- self .account .connection_broken = False
137- self .account .last_error_message = ""
138- self .account .save (
140+ self .instance .last_sync_at = timezone .now ()
141+ self .instance .connection_broken = False
142+ self .instance .last_error_message = ""
143+ self .instance .save (
139144 update_fields = [
140145 "last_sync_at" ,
141146 "connection_broken" ,
@@ -233,6 +238,7 @@ def _sync_series_episode_collection(self, show_item, row):
233238 user = self .user ,
234239 item = show_item ,
235240 source = "sonarr" ,
241+ source_instance_id = self .instance .pk ,
236242 quality_label = "" ,
237243 source_updated_at = self ._parse_source_timestamp (row ),
238244 )
@@ -260,6 +266,7 @@ def _sync_series_episode_collection(self, show_item, row):
260266 user = self .user ,
261267 item = episode_item ,
262268 source = "sonarr" ,
269+ source_instance_id = self .instance .pk ,
263270 quality_label = self ._extract_episode_quality_label (episode_row ),
264271 source_updated_at = self ._parse_source_timestamp (episode_row ),
265272 )
@@ -456,7 +463,11 @@ def _prune_series_collection_state(self, show_item, *, keep_episode_item_ids=Non
456463 media_type = MediaTypes .EPISODE .value ,
457464 )
458465 .exclude (id__in = keep_episode_item_ids )
459- .filter (source_states__user = self .user , source_states__source = "sonarr" )
466+ .filter (
467+ source_states__user = self .user ,
468+ source_states__source = "sonarr" ,
469+ source_states__source_instance_id = self .instance .pk ,
470+ )
460471 .values_list ("id" , flat = True )
461472 .distinct ()
462473 )
@@ -466,6 +477,7 @@ def _prune_series_collection_state(self, show_item, *, keep_episode_item_ids=Non
466477 user = self .user ,
467478 item = episode_item ,
468479 source = "sonarr" ,
480+ source_instance_id = self .instance .pk ,
469481 )
470482
471483 if keep_episode_item_ids :
@@ -475,13 +487,15 @@ def _prune_series_collection_state(self, show_item, *, keep_episode_item_ids=Non
475487 user = self .user ,
476488 item = show_item ,
477489 source = "sonarr" ,
490+ source_instance_id = self .instance .pk ,
478491 )
479492
480493 def _retire_legacy_series_collection_entry (self , show_item ):
481494 """Delete the legacy show-level Sonarr row once episode rows exist."""
482495 if not show_item .source_states .filter (
483496 user = self .user ,
484497 source = "sonarr" ,
498+ source_instance_id = self .instance .pk ,
485499 ).exists ():
486500 return
487501
0 commit comments