diff --git a/sok/models.py b/sok/models.py index 4e83a51..3f6b7e6 100644 --- a/sok/models.py +++ b/sok/models.py @@ -103,6 +103,24 @@ class Publication(models.Model): def relevant_referenced_by(self) -> QuerySet: return self.referenced_by.filter(exclusion_criteria__isnull=True) + def stage_added(self) -> int: + if not self.is_relevant: + return 10000 + + if self.sources.exists(): + return 0 + + if self.referenced_by.filter(exclusion_criteria__isnull=True, sources__isnull=False) or self.references.filter(exclusion_criteria__isnull=True, sources__isnull=False): + return 1 + + if ref_by := self.referenced_by.filter(exclusion_criteria__isnull=True): + stages = set([ref.stage_added() for ref in ref_by]) + return 1 + sorted(stages)[0] + + if refs := self.references.filter(exclusion_criteria__isnull=True): + stages = set([ref.stage_added() for ref in refs]) + return 1 + sorted(stages)[0] + @property def stage(self) -> Optional[str]: if not self.is_relevant: @@ -113,24 +131,27 @@ class Publication(models.Model): return 'primary' # Referenced by primary (backward snowballing) - # TODO make transitive + # DONE make transitive if self.referenced_by.filter(exclusion_criteria__isnull=True, sources__isnull=False): return 'secondary' # References a primary (forward snowballing) - # TODO make transitive if self.references.filter(exclusion_criteria__isnull=True, sources__isnull=False): return 'tertiary' - if ref_by := self.referenced_by.filter(exclusion_criteria__isnull=True): - stages = set([ref.stage for ref in ref_by]) - if 'secondary' in stages: return 'sec-secondary' - elif 'tertiary' in stages: return 'sec-tertiary' + # prefer secondary over tertiary regardless of stage for now + exclude = False + if self.referenced_by.filter(exclusion_criteria__isnull=True): + stage = self.stage_added() + if stage > 10000: exclude = True + else: return str(stage) + '-secondary' - if refs := self.references.filter(exclusion_criteria__isnull=True): - stages = set([ref.stage for ref in ref_by]) - if 'secondary' in stages: return 'tert-secondary' - elif 'tertiary' in stages: return 'tert-tertiary' + if self.references.filter(exclusion_criteria__isnull=True): + stage = self.stage_added() + if stage > 10000: return 'excluded-by-ref' + else: return str(stage) + '-tertiary' + + if exclude: return 'excluded-by-ref' return None