Skip to content

Commit 9ea4bdf

Browse files
authored
Merge pull request #248 from Drazzilb08/dev
Dev
2 parents 4373af5 + f9e4f51 commit 9ea4bdf

File tree

5 files changed

+88
-60
lines changed

5 files changed

+88
-60
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,4 @@ test2.py
6868
/tests
6969
pyproject.toml
7070
pyproject.toml
71+
/config

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.1
1+
2.0.3

modules/labelarr.py

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,22 @@ def sync_to_plex(
4343
List[Dict]: List of label changes applied or identified.
4444
"""
4545
tag_ids: Dict[str, Optional[int]] = {}
46-
# Map label names to their corresponding tag IDs in ARR
4746
for label in labels:
4847
tag_id = app.get_tag_id_from_name(label)
4948
if tag_id:
5049
tag_ids[label] = tag_id
5150

52-
# Create lookup dictionaries for media items based on different IDs
51+
# Create lookups
52+
tmdb_imdb_lookup = {
53+
(media.get("tmdb_id"), media.get("imdb_id")): media
54+
for media in media_dict
55+
if media.get("tmdb_id") is not None and media.get("imdb_id")
56+
}
57+
tvdb_imdb_lookup = {
58+
(media.get("tvdb_id"), media.get("imdb_id")): media
59+
for media in media_dict
60+
if media.get("tvdb_id") is not None and media.get("imdb_id")
61+
}
5362
tmdb_lookup = {
5463
media["tmdb_id"]: media
5564
for media in media_dict
@@ -66,7 +75,9 @@ def sync_to_plex(
6675
if media.get("imdb_id") is not None
6776
}
6877
fallback_lookup = {
69-
(media["normalized_title"], media["year"]): media for media in media_dict
78+
(media["normalized_title"], media["year"]): media
79+
for media in media_dict
80+
if "normalized_title" in media and "year" in media
7081
}
7182

7283
data_dict: List[Dict] = []
@@ -95,16 +106,16 @@ def sync_to_plex(
95106
]
96107
except AttributeError:
97108
logger.error(
98-
f"Error fetching labels for {library_item.title} ({library_item.year})"
109+
f"Error fetching labels for {getattr(library_item, 'title', str(library_item))} (no labels)"
99110
)
100111
continue
101112

113+
# Safely extract IDs
102114
ids: Dict[str, Optional[str]] = {
103115
"tmdb": None,
104116
"tvdb": None,
105117
"imdb": None,
106118
}
107-
# Extract IDs from Plex item's GUIDs for matching
108119
for guid in getattr(library_item, "guids", []):
109120
guid_str = getattr(guid, "id", "")
110121
if guid_str.startswith("tmdb://"):
@@ -117,50 +128,62 @@ def sync_to_plex(
117128
media_item: Optional[Dict] = None
118129
match_type: str = "unknown"
119130

120-
# Attempt to find media item by TMDB ID if valid
121-
if ids["tmdb"] and ids["tmdb"].isdigit():
122-
media_item = tmdb_lookup.get(int(ids["tmdb"]))
131+
# 1. Prefer TMDB+IMDB or TVDB+IMDB
132+
tmdb_id = ids.get("tmdb")
133+
imdb_id = ids.get("imdb")
134+
tvdb_id = ids.get("tvdb")
135+
136+
# Prefer TMDB+IMDB
137+
if tmdb_id and tmdb_id.isdigit() and imdb_id:
138+
key = (int(tmdb_id), imdb_id)
139+
media_item = tmdb_imdb_lookup.get(key)
123140
if media_item:
124-
media_id = media_item["tmdb_id"]
125-
plex_id = ids["tmdb"]
126-
match_type = (
127-
f"TMDB Media ID: {media_id} - Plex ID {plex_id}"
128-
)
141+
match_type = f"TMDB+IMDB MATCH: TMDB {tmdb_id} & IMDB {imdb_id}"
129142

130-
# Fallback to TVDB ID if no TMDB match found
131-
if not media_item and ids["tvdb"] and ids["tvdb"].isdigit():
132-
media_item = tvdb_lookup.get(int(ids["tvdb"]))
143+
# Next try TVDB+IMDB
144+
if not media_item and tvdb_id and tvdb_id.isdigit() and imdb_id:
145+
key = (int(tvdb_id), imdb_id)
146+
media_item = tvdb_imdb_lookup.get(key)
133147
if media_item:
134-
media_id = media_item["tvdb_id"]
135-
plex_id = ids["tvdb"]
136-
match_type = (
137-
f"TVDB Media ID: {media_id} - Plex ID {plex_id}"
138-
)
148+
match_type = f"TVDB+IMDB MATCH: TVDB {tvdb_id} & IMDB {imdb_id}"
139149

140-
# Fallback to IMDB ID if no TMDB or TVDB match found
141-
if not media_item and ids["imdb"]:
142-
media_item = imdb_lookup.get(ids["imdb"])
150+
# 2. Fallback to just TMDB, TVDB, IMDB
151+
if not media_item and tmdb_id and tmdb_id.isdigit():
152+
media_item = tmdb_lookup.get(int(tmdb_id))
143153
if media_item:
144-
media_id = media_item["imdb_id"]
145-
plex_id = ids["imdb"]
146-
match_type = (
147-
f"IMDB Media ID: {media_id} - Plex ID {plex_id}"
148-
)
154+
match_type = f"TMDB MATCH: {tmdb_id}"
149155

150-
# Final fallback to normalized title and year matching
151-
if not media_item:
152-
key = (normalize_titles(library_item.title), library_item.year)
153-
media_item = fallback_lookup.get(key)
156+
if not media_item and tvdb_id and tvdb_id.isdigit():
157+
media_item = tvdb_lookup.get(int(tvdb_id))
158+
if media_item:
159+
match_type = f"TVDB MATCH: {tvdb_id}"
160+
161+
if not media_item and imdb_id:
162+
media_item = imdb_lookup.get(imdb_id)
154163
if media_item:
155-
match_type = "TITLE/YEAR MATCH"
164+
match_type = f"IMDB MATCH: {imdb_id}"
156165

166+
# 3. Final fallback to normalized title and year
167+
if not media_item:
168+
norm_title = normalize_titles(getattr(library_item, "title", ""))
169+
item_year = getattr(library_item, "year", None)
170+
if item_year is not None:
171+
key = (norm_title, item_year)
172+
media_item = fallback_lookup.get(key)
173+
if media_item:
174+
match_type = "TITLE/YEAR MATCH"
175+
else:
176+
logger.debug(
177+
f"Skipping fallback match for '{getattr(library_item, 'title', str(library_item))}' as no 'year' attribute is present (likely not a movie/show item)"
178+
)
179+
180+
# 4. Only proceed if a real match was found
157181
if media_item:
158182
logger.debug(
159-
f"Matched '{library_item.title}' ({library_item.year}) using {match_type} lookup to '{media_item['title']}' ({media_item['year']})"
183+
f"Matched '{getattr(library_item, 'title', str(library_item))}' ({getattr(library_item, 'year', '-')}) using {match_type} to '{media_item.get('title', '-')}' ({media_item.get('year', '-')})"
160184
)
161185
add_remove: Dict[str, str] = {}
162-
163-
# Determine which labels to add or remove based on ARR tags and Plex labels
186+
# Decide add/remove per label
164187
for tag, id in tag_ids.items():
165188
if tag not in plex_item_labels and id in media_item["tags"]:
166189
add_remove[tag] = "add"
@@ -176,8 +199,8 @@ def sync_to_plex(
176199
if add_remove:
177200
data_dict.append(
178201
{
179-
"title": library_item.title,
180-
"year": library_item.year,
202+
"title": getattr(library_item, "title", str(library_item)),
203+
"year": getattr(library_item, "year", None),
181204
"add_remove": add_remove,
182205
}
183206
)

modules/upgradinatorr.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -271,35 +271,34 @@ def process_instance(
271271
media_ids: List[int] = [item["media_id"] for item in filtered_media_dict]
272272
# Search logic: trigger searches and tag after search
273273
for item in filtered_media_dict:
274-
logger.info(
275-
f"Processing: {item['title']} ({item['year']}) [ID: {item['media_id']}]"
276-
)
277-
# ══════════════════════════════════════════════════════════════════════
274+
logger.debug("") # Blank line before block
278275
logger.debug("═" * 70)
279276
logger.debug(
280277
f"[PROCESSING] {item['title']} ({item['year']}) | ID: {item['media_id']}"
281278
)
282279
logger.debug("═" * 70)
283-
if search_count >= count:
284-
logger.debug(
285-
f"🔁 Reached search count limit ({search_count} >= {count}), stopping early."
286-
)
287-
break
280+
288281
if item["seasons"] is None:
289-
# Search entire media if no seasons
290282
logger.debug(
291283
f"Searching media without seasons for media ID: {item['media_id']}"
292284
)
293285
search_response = app.search_media(item["media_id"])
294286
process_search_response(search_response, item["media_id"], app, logger)
287+
logger.debug(
288+
f" [TAG] Adding tag {checked_tag_id} to media ID: {item['media_id']}"
289+
)
290+
app.add_tags(item["media_id"], checked_tag_id)
295291
search_count += 1
296292
if search_count >= count:
297293
logger.debug(
298294
f"🔁 Reached search count limit after non-season search ({search_count} >= {count}), breaking."
299295
)
296+
logger.debug("─" * 70)
297+
logger.debug(f"[END] Finished: {item['title']} ({item['year']}) | ID: {item['media_id']}")
298+
logger.debug("─" * 70)
299+
logger.debug("")
300300
break
301301
else:
302-
# Search monitored seasons
303302
searched = False
304303
for season in item["seasons"]:
305304
if season["monitored"]:
@@ -315,20 +314,25 @@ def process_instance(
315314
searched = True
316315

317316
if searched:
317+
logger.debug(
318+
f" [TAG] Adding tag {checked_tag_id} to media ID: {item['media_id']}"
319+
)
320+
app.add_tags(item["media_id"], checked_tag_id)
318321
search_count += 1
319322
if search_count >= count:
320323
logger.debug(
321324
f"🔁 Reached series-based search count limit ({search_count} >= {count}), breaking."
322325
)
326+
logger.debug("─" * 70)
327+
logger.debug(f"[END] Finished: {item['title']} ({item['year']}) | ID: {item['media_id']}")
328+
logger.debug("─" * 70)
329+
logger.debug("")
323330
break
324-
# Tagging logic: add checked tag after processing
325-
logger.debug(
326-
f" [TAG] Adding tag {checked_tag_id} to media ID: {item['media_id']}"
327-
)
328-
app.add_tags(item["media_id"], checked_tag_id)
329-
logger.debug(
330-
f"[END] Finished: {item['title']} ({item['year']}) | ID: {item['media_id']}\n"
331-
)
331+
332+
logger.debug("─" * 70)
333+
logger.debug(f"[END] Finished: {item['title']} ({item['year']}) | ID: {item['media_id']}")
334+
logger.debug("─" * 70)
335+
logger.debug("") # Blank line after block
332336
logger.info(f"Finished processing: {item['title']} ({item['year']})")
333337

334338
logger.info(

util/template/config_template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
"radarr_count": 0,
9191
"sonarr_count": 0,
9292
"tag_name": "",
93-
"ignore_tags": "",
93+
"ignore_tag": "",
9494
"enable_batching": false,
9595
"instances": []
9696
},

0 commit comments

Comments
 (0)