@@ -554,11 +554,12 @@ def apply(self) -> None:
554
554
555
555
def unapply (self ) -> None :
556
556
"""
557
- Remove title modifications:
558
- 1. Create Delta URLs for affected Curated URLs to explicitly clear titles
559
- 2. Remove generated titles from affected Delta URLs
560
- 3. Clean up Delta URLs that become identical to their Curated URL
561
- 4. Clear resolution tracking
557
+ Remove title modifications, maintaining pattern precedence:
558
+ 1. Find any remaining patterns that match each URL
559
+ 2. Apply most specific matching pattern's title if one exists
560
+ 3. Otherwise revert to curated title or clear title
561
+ 4. Update title resolution tracking
562
+ 5. Clean up redundant deltas
562
563
"""
563
564
DeltaUrl = apps .get_model ("sde_collections" , "DeltaUrl" )
564
565
CuratedUrl = apps .get_model ("sde_collections" , "CuratedUrl" )
@@ -569,16 +570,36 @@ def unapply(self) -> None:
569
570
affected_deltas = self .delta_urls .all ()
570
571
affected_curated = self .curated_urls .all ()
571
572
573
+ # Get all other title patterns for this collection
574
+ other_patterns = DeltaTitlePattern .objects .filter (collection = self .collection ).exclude (id = self .id )
575
+
572
576
# Process each affected delta URL
573
577
for delta in affected_deltas :
574
578
curated = CuratedUrl .objects .filter (collection = self .collection , url = delta .url ).first ()
575
579
576
- if not curated :
577
- # Scenario 1: Delta only - clear generated title
578
- delta .generated_title = ""
579
- delta .save ()
580
- else :
581
- # Scenario 2: Both exist - revert to curated title
580
+ # Find next most specific matching pattern if any
581
+ matching_patterns = [p for p in other_patterns if re .search (p .get_regex_pattern (), delta .url )]
582
+
583
+ next_pattern = None
584
+ if matching_patterns :
585
+ # Sort by number of URLs matched (ascending) to find most specific
586
+ next_pattern = min (matching_patterns , key = lambda p : p .get_url_match_count ())
587
+
588
+ if next_pattern :
589
+ # Apply next most specific pattern's title
590
+ new_title , error = next_pattern .generate_title_for_url (delta )
591
+ if error :
592
+ DeltaResolvedTitleError .objects .update_or_create (
593
+ delta_url = delta , defaults = {"title_pattern" : next_pattern , "error_string" : error }
594
+ )
595
+ else :
596
+ delta .generated_title = new_title
597
+ delta .save ()
598
+ DeltaResolvedTitle .objects .update_or_create (
599
+ delta_url = delta , defaults = {"title_pattern" : next_pattern , "resolved_title" : new_title }
600
+ )
601
+ elif curated :
602
+ # No other patterns match, revert to curated title
582
603
delta .generated_title = curated .generated_title
583
604
delta .save ()
584
605
@@ -590,18 +611,47 @@ def unapply(self) -> None:
590
611
)
591
612
if fields_match :
592
613
delta .delete ()
614
+ else :
615
+ # No curated URL or other patterns, clear title
616
+ delta .generated_title = ""
617
+ delta .save ()
593
618
594
619
# Handle curated URLs that don't have deltas
595
620
for curated in affected_curated :
596
621
if not DeltaUrl .objects .filter (url = curated .url ).exists ():
597
- # Scenario 3: Curated only - create delta with cleared title
598
- fields = {
599
- f .name : getattr (curated , f .name ) for f in curated ._meta .fields if f .name not in ["id" , "collection" ]
600
- }
601
- fields ["generated_title" ] = ""
602
- DeltaUrl .objects .create (collection = self .collection , ** fields )
603
-
604
- # Clear resolution tracking
622
+ # Find any matching patterns
623
+ matching_patterns = [p for p in other_patterns if re .search (p .get_regex_pattern (), curated .url )]
624
+
625
+ if matching_patterns :
626
+ # Apply most specific pattern's title
627
+ next_pattern = min (matching_patterns , key = lambda p : p .get_url_match_count ())
628
+
629
+ # Copy all fields from curated
630
+ fields = {
631
+ f .name : getattr (curated , f .name )
632
+ for f in curated ._meta .fields
633
+ if f .name not in ["id" , "collection" ]
634
+ }
635
+
636
+ # Generate and apply new title
637
+ new_title , error = next_pattern .generate_title_for_url (curated )
638
+ if not error :
639
+ fields ["generated_title" ] = new_title
640
+ delta = DeltaUrl .objects .create (collection = self .collection , ** fields )
641
+ DeltaResolvedTitle .objects .create (
642
+ title_pattern = next_pattern , delta_url = delta , resolved_title = new_title
643
+ )
644
+ else :
645
+ # No other patterns, create delta with cleared title
646
+ fields = {
647
+ f .name : getattr (curated , f .name )
648
+ for f in curated ._meta .fields
649
+ if f .name not in ["id" , "collection" ]
650
+ }
651
+ fields ["generated_title" ] = ""
652
+ DeltaUrl .objects .create (collection = self .collection , ** fields )
653
+
654
+ # Clear resolution tracking for this pattern
605
655
DeltaResolvedTitle .objects .filter (title_pattern = self ).delete ()
606
656
DeltaResolvedTitleError .objects .filter (title_pattern = self ).delete ()
607
657
0 commit comments