Basically a fork from https://github.com/blochberger/sokman but with the intention of adding a visual interface as well
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
1.5 KiB
60 lines
1.5 KiB
from typing import Set, Tuple
|
|
|
|
from django.core.management.base import BaseCommand, CommandParser
|
|
from django.db.models import Count, Q
|
|
|
|
from sok.models import Publication
|
|
|
|
|
|
class Command(BaseCommand):
|
|
|
|
def echo(self, msg: str):
|
|
self.stdout.write(msg)
|
|
|
|
# BaseCommand
|
|
|
|
def add_arguments(self, parser: CommandParser):
|
|
parser.add_argument('--min-citations', type=int, default=0)
|
|
parser.add_argument('--pk', action='store_true')
|
|
|
|
def graphviz(self, pk: bool, min_citations: int) -> None:
|
|
publications = Publication.objects.filter(exclusion_criteria__isnull=True).annotate(
|
|
citation_count=Count(
|
|
'referenced_by',
|
|
filter=Q(exclusion_criteria__isnull=True),
|
|
distinct=True,
|
|
),
|
|
).filter(citation_count__gte=min_citations)
|
|
|
|
self.echo("digraph G {")
|
|
self.echo("\trankdir = RL;")
|
|
|
|
graph: Set[Tuple[int, int]] = set()
|
|
|
|
for publication in publications:
|
|
|
|
if publication.stage != 'primary':
|
|
continue
|
|
|
|
for reference in publication.relevant_references:
|
|
|
|
if reference not in publications:
|
|
continue
|
|
|
|
graph.add((publication.pk, reference.pk))
|
|
if (reference.pk, publication.pk) in graph:
|
|
self.stderr.write(self.style.ERROR(
|
|
f"CYCLE: {publication.cite_key} <-> {reference.cite_key}"
|
|
))
|
|
|
|
if pk:
|
|
self.echo(f'\t"{publication.pk}" -> "{reference.pk}";')
|
|
else:
|
|
self.echo(f'\t"{publication.cite_key}" -> "{reference.cite_key}";')
|
|
|
|
self.echo("}")
|
|
|
|
def handle(self, *args, **options) -> None:
|
|
min_citations: int = options['min_citations']
|
|
pk: bool = options['pk']
|
|
self.graphviz(pk, min_citations)
|
|
|